matplotlib with wxPython GUIs
August 1st, 2008 at 9:24 amAs I wrote in the last post, I found matplotlib to be a very nice library for plotting. So, considering that I really plan to use it for my Python programs at work, I’ve spent a little time to write some proof-of-concept code (I do this often when learning a new library. Nothing serves as a better reference than your own code).
The first demo I wrote displays a bar plot, allowing the user to change the data shown on it in real-time, as well as using the matplotlib navigation toolbar and saving the plot to a file. Additionally, it allows some basic interaction with the plot (clicking on a bar brings up a message box) and playing with the plot’s properties like the grid and the width of the bars.
You can download this demo from here.
The second demo is rather more sophisticated. It explores the dynamic abilities of matplotlib, which allows smooth and flicker-less animation. This demo features a “live” graph that runs continuously (unless the user asks it to pause). The user can explore the graph by selecting limits for the X and Y axes, and select whether he wants to see the grid and the X axis labels.
It can be downloaded from here.
Related posts:

August 1st, 2008 at 10:54 am
Awesome, thanks.
August 6th, 2008 at 12:46 am
Fantastic. I’ve been using matplotlib for a while, and have done a bit of wxPython, but have never put the two together. This should get me started. Many thanks.
August 12th, 2008 at 5:35 pm
Live graph one failed with :
RuntimeError: xdata and ydata must be the same length
August 12th, 2008 at 8:38 pm
Chris,
Are you sure you didn’t change anything and / or have the up-to-date version of matplotlib ?
The only two places in the code that populate the plot with data are:
1. In the end of init_plot()
self.plot_data = self.axes.plot( self.data, linewidth=1, color=(1, 1, 0), )[0]This only fills in the y axis, x will be automatically done by axes.plot
2. In the end of draw_plot()
self.plot_data.set_xdata(np.arange(len(self.data))) self.plot_data.set_ydata(np.array(self.data))These two obviously create arrays of the same length.
August 13th, 2008 at 1:25 am
Sorry - was using latest marked stable on Gentoo 0.91.2 - update to matplotlib-0.98.1 fixed it.
Afaik the problem was between those two lines of draw_plot. Once you updated x - and before you updated y - the two didn’t match. Obviously now matplotlib handle it safely.
Thanks
September 10th, 2008 at 2:54 pm
Eli, looks great! I was just Googling around for wxPython & matplotlib coming across these examples; great starting points.
One thing: when trying on my Mac, the second example didn’t fully work: the radio buttons weren’t available, and I saw only one run of the live data. Could that be because of the wxPython version that ships with OS X 10.5? It’s 2.8.4.0, matplotlib is 0.98.0. Or is it just intrinsic to the OS X GUI?
September 10th, 2008 at 5:40 pm
Evert,
Your version of wxPython does look a bit old…
Though I don’t know much about OS X
September 10th, 2008 at 10:08 pm
Tried with a up-to-date version (2.8.8.1) of wxPython; no luck.
So I guess it’s more intrinsic to OS X/Aqua or so.
If I ever find out, I might come back here to let you know; but that could be a few months (no hurry getting this right, as I don’t need it yet. I’m just playing around right now).
September 15th, 2008 at 6:42 pm
Eli, for your (and possibly other people’s) records: I now know what caused this.
wxStaticBox/Sizer needs to be created before any of the controls inside it are created, otherwise it’ll draw on top of those of controls, and while you may be able to see them, you cannot “reach” (click) them. MS Windows (XP) is apparently a bit more forgiving there, so it worked for you (or it’s actually broken there, as I don’t know what’s the correct way to do this); apparently, with GTK it can even crash.
So, the solution is to take the following two lines in the BoundControlBox’s __init__() method (wx_mpl_dynamic_graph.py), and move them up, just before the self.radio_auto is created:
self.value = initval box = wx.StaticBox(self, -1, label) sizer = wx.StaticBoxSizer(box, wx.VERTICAL) self.radio_auto = wx.RadioButton(self, -1, label="Auto", style=wx.RB_GROUP)Then it works splendidly for me, and probably also on other platforms/window environments.
More details at the wxwidgets.org wiki or eg this post in a mailinglist.
September 19th, 2008 at 9:18 am
Evert,
Thanks. I’ve updated the file to reflect this fix.
September 30th, 2008 at 4:34 pm
Exactly what I was looking for. I have graphs in my application, but not on figurecanvas. I was just trying to get a barchart with wx and was headed down the wrong track. Snippits will save me some time. Thanks