On Sun, May 18, 2014 at 9:00 AM, Marcus Müller <marcus.muel...@ettus.com>wrote:
> Hi, > I think real-time and matplotlib kind of contradict in the first place - > really, matplotlib's performance is terrible. As a rule, it's Assisi > generally a bad idea to let your data file update your GUI. Usually, you > want something like a check every tenth of a second, if data has arrived, > and then updating your GUI accordingly. Otherwise, you will either end up > with refresh rates that are unnecessarily high (e.g. 200fps) or a GUI not > reacting to events (e.g. resizing) by redrawing. So that's two things bad > about your approach. > > As I explained, you'll have a hard time getting GUI to run in a block, > since by principle, GR blocks can not run in the main thread, and things > like Tim's qwt plot go through death, wind, fire and message passing to get > data out of the blocks' threads and into the GUI thread. > > Anyway, with matplotlib and pyqt to wrap the canvas in a qt application > and a little googling you can hack together guis that should work with the > qt generate option - no guarantee though. I'd rather get used to qwt in > most cases than stick with matplotlib... > > Greetings, > Marcus > I agree with Marcus. Don't try and use/abuse matplotlib for this purpose. I pointed to Tim's repo of PyQT/QWT blocks to show you how to use those tools to build GUIs in Python blocks. Tom > On May 18, 2014 2:25:00 PM CEST, Activecat <active...@gmail.com> wrote: > >> On Fri, May 2, 2014 at 8:56 PM, Tom Rondeau <t...@trondeau.com> wrote: >> >>> On Fri, May 2, 2014 at 8:49 AM, Marcus Müller >>> <marcus.muel...@ettus.com>wrote: >>> >>>> Hi Activecat, >>>> >>>> typical GUI problem; background is that X applications are inherently >>>> hard to multithread, which basically requires graphical toolkits to run in >>>> a main loop. This conflicts with every block being run in its own thread. >>>> >>>> The easiest solution nowadays should be that you generate a QT flow >>>> graph in GRC, use PyQT to generate your GUI, register a message handler and >>>> integrate matplotlib (there are examples out there, just don't have one at >>>> my fingertips right now), and use the message passing interface to get data >>>> out of your flow graph into your GUI. >>>> >>>> Greetings, >>>> Marcus >>>> >>> >>> Tim's written a number of blocks like this: >>> https://github.com/osh/gr-pyqt >>> >>> Tom >>> >> >> >> >> The examples (https://github.com/osh/gr-pyqt) are using Qt and Qwt to >> plot graphs, not matplotlib. >> (When all the "import pylab" are removed, everything still work as usual, >> except for pylab.fftshift ). >> >> In order to stick to matplotlib, I created a custom block, register a >> message handler, and use the message passing interface to get data out from >> the flowgraph into the custom block. (Everything is as described by Marcus >> as above, except I do not use QT.) >> For this flowgraph, Generate-Option="No GUI" >> >> When I put "self.axes1.figure.canvas.draw()" or "pyplot.draw()" in the >> message handler, the same error still happens: >> ERROR: handler caught exception: main thread is not in main loop >> >> Question: >> How to get rid of this error? >> Or, does this mean plotting using matplotlib is not an option ..? >> >> My objective is to plot graphs in realtime using matplotlib. >> I try to stick to Matplotlib because it is the tool I that I am using for >> numerical analysis. >> >> >> >> The custom block is coded as: >> >> #!/usr/bin/env python >> # -*- coding: utf-8 -*- >> >> import numpy >> from gnuradio import gr >> >> import pmt >> from matplotlib import pyplot >> >> >> class matplotlib4(gr.sync_block): >> >> def __init__(self): >> gr.sync_block.__init__(self, >> name="matplotlib4", >> in_sig=None, >> out_sig=None) >> >> pyplot.ion() >> self.fig1 = pyplot.figure() >> self.ax1 = self.fig1.add_subplot(2,1,1) >> self.ax1.set_ylabel('Real') >> self.ax1.set_xlabel('time') >> self.ax1.set_ylim(-1.2, 1.2) >> self.ax1.grid(True) >> self.line1, = self.ax1.plot( [0.3]*1000 ) >> self.line2, = self.ax1.plot( [0.3]*1000 ) >> self.axes1 = pyplot.gca() >> pyplot.draw() # no error of "main thread is not in main >> loop" >> pyplot.show() # no error of "main thread is not in main >> loop" >> >> self.message_port_register_in( pmt.intern("cpdus")) >> self.set_msg_handler(pmt.intern("cpdus"), self.handler4) >> >> >> def handler4( self, msg ): >> samples = pmt.cdr(msg) >> data = numpy.array( pmt.c32vector_elements(samples), >> dtype=numpy.complex64 ) >> >> self.line1.set_ydata( data.real ) >> self.line2.set_ydata( data.imag ) >> #self.fig1.canvas.draw() # handler caught >> exception: main thread is not in main loop >> #pyplot.draw() # handler caught >> exception: main thread is not in main loop >> #self.axes1.figure.canvas.draw() # handler caught >> exception: main thread is not in main loop >> print "handler4(): x.size={}".format( data.size ) >> >> >> def work(self, input_items, output_items): >> print "matplotlib4.work(): *** This should not be >> invoked*** " >> return len(input_items[0]) >> >> >> >> >> Flowgraph being used for this test: >> >> >> >> >> >> >> >> ------------------------------ >> >> Discuss-gnuradio mailing list >> Discuss-gnuradio@gnu.org >> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio >> >> > -- > Sent from my Android device with K-9 Mail. Please excuse my brevity. > > _______________________________________________ > Discuss-gnuradio mailing list > Discuss-gnuradio@gnu.org > https://lists.gnu.org/mailman/listinfo/discuss-gnuradio > >
_______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org https://lists.gnu.org/mailman/listinfo/discuss-gnuradio