Integrating plots with existing PyGTK application

Hi everyone,

I am a developer on a PyGTK application for Earth Science research and education called SEATREE ( http://geosys.usc.edu/projects/seatree/wiki ) and we are trying to integrate some pylab plots.

I can successfully create and use a pylab frame/window inside of our GTK application using the following sequence (note that all of this is called AFTER the application has launched and the GTK main loop has started):

···

-------------------------------------
import math
import pylab as p
import matplotlib
from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar matplotlib.use('GTK')

p.figure()
//set up the figure
//connect actions using p.connect('signal name', function)
p.show()
-------------------------------------

Then, once I'm done with the plot and it is closed, p.close() is called.

All of that works fine, and I actually like the blocking nature of the p.show() method (I know this probably isn't the best way since I already have a GTK main loop going). The problem arises when I try to display the plot again. If I just call the p.show() method for a 2nd time, it does not block execution of my function, and the plot shows up but is unresponsive with full CPU utilization. My main GTK window for the application is enabled and responsive during this time.

I then tried using the following code to show the window (either both times or just the 2nd time around):

-------------------------------------
for manager in Gcf.get_all_fig_managers():
        manager.window.show()
-------------------------------------

But I get an error that is very strange, as it references Tkinter even though I am using GTK:

-------------------------------------
Traceback (most recent call last):
  File "/home/kevin/workspace_seatree/SEATREE/py-drivers/py-hc/flowGUI.py", line 379, in editVisc
    manager.window.show()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1724, in __getattr__
    return getattr(self.tk, attr)
AttributeError: show
-------------------------------------

Finally, I tried just not calling anything after p.frame() the second time through (besides doing the signal connecting again), and this time the plot window will show up, but signals will not be processed (including trying to close the plot with the 'x' on the window frame).

I also tried just embedding a FigureCanvasGTK object displaying the figure to my own gtk.Dialog object, which works for displaying the plot, but I couldn't figure out how to get the pylab events to be processed and connected (I need to modify the plot by clicking on parts of it). If I could figure out the even handling, this would actually be the preferred method of showing the plot. This is the code for this attempt:

-------------------------------------
self.dialog = gtk.Dialog(title=title, parent=parent, flags= gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.canvas = FigureCanvasGTK(self.figure)
self.dialog.vbox.pack_start(self.canvas)
self.dialog.show_all()
self.dialog.show()
-------------------------------------

Does anyone have any suggestions? Thanks a ton for making it this far through my long message!

Kevin Milner

P.S. see full source here: (the pylab stuff is dirty cause it's in debugging stages)
See bottom for the p.show() call: http://geosys.usc.edu/projects/seatree/browser/py-drivers/py-hc/flowGUI.py
Event processing/plot creation and manipulation: http://geosys.usc.edu/projects/seatree/browser/py-drivers/py-hc/manipulate_hc.py

For the "use" directive to be honored, it must be called before you
import pylab. If it is after, as in your example code, pylab will
respect the setting in your matplotlibrc file -- see
http://matplotlib.sf.net/matplotlibrc (this is likely why you are
getting unexplained references to tk code).

But you should not be using pylab, since you are embedding mpl in a
GTK GUI. Instead, you should be using the matplotlob API,
specifically the idioms for embedding mpl in gtk -- it takes a little
more work up front but it is the only acceptable way to use mpl in a
GTK app

http://matplotlib.sf.net/examples/embedding_in_gtk.py
http://matplotlib.sourceforge.net/examples/embedding_in_gtk2.py

See also the OO FAQ and the API tutorial for more insight into using
the API directly rather than the pylab interface

http://matplotlib.sf.net/faq.html#OO
http://matplotlib.sf.net/leftwich_tut.txt

JDH

JDH

···

On Thu, Feb 21, 2008 at 3:07 PM, Kevin Milner <kmilner@...1887...> wrote:

Hi everyone,

I am a developer on a PyGTK application for Earth Science research and
education called SEATREE ( http://geosys.usc.edu/projects/seatree/wiki )
and we are trying to integrate some pylab plots.

I can successfully create and use a pylab frame/window inside of our GTK
application using the following sequence (note that all of this is
called AFTER the application has launched and the GTK main loop has
started):

-------------------------------------
import math
import pylab as p
import matplotlib
from matplotlib.backends.backend_gtk import FigureCanvasGTK,
NavigationToolbar
matplotlib.use('GTK')

Given the frequency of this question, maybe it would be
a good idea on the main project page
<URL:http://matplotlib.sourceforge.net/>
to augment the text

        The plotting functions in the pylab interface have
        a high degree of Matlab® compatibility.

to include a caveat:

        The plotting functions in the pylab interface have
        a high degree of Matlab® compatibility. (These are
        suitable for plotting scripts but NOT for GUI
        embeddding, which should use the matplotlib API.)

fwiw,
Alan Isaac

···

On Thu, 21 Feb 2008, John Hunter apparently wrote:

you should not be using pylab, since you are embedding mpl in a
GTK GUI.