|
From: | Tom Rondeau |
Subject: | Re: [Discuss-gnuradio] matplotlib runtime error |
Date: | Sun, 18 May 2014 12:52:40 -0400 |
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
On May 18, 2014 2:25:00 PM CEST, Activecat <address@hidden> wrote:When I put "self.axes1.figure.canvas.draw()" or "pyplot.draw()" in the message handler, the same error still happens:On Fri, May 2, 2014 at 8:56 PM, Tom Rondeau <address@hidden> wrote:
On Fri, May 2, 2014 at 8:49 AM, Marcus Müller <address@hidden> wrote:
MarcusGreetings,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.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.
Tim's written a number of blocks like this: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"
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 = "" 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:
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
Discuss-gnuradio mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
[Prev in Thread] | Current Thread | [Next in Thread] |