1

programming noob here. I'm trying to use a matplotlib widget in a PyQt4 GUI. The widget is similar to matplotlib's example for qt.

At some point the user needs to click on the plot, which I thought something like ginput() would handle. However, this doesn't work because the figure doesn't have a manager (see below). Note that this is very similar to another question but it never got answered.

AttributeError: 'NoneType' object has no attribute 'manager'
Figure.show works only for figures managed by pyplot, normally created by pyplot.figure().

I'm assuming by "normally" there's a way around this.

Another simple script to demonstrate:

from __future__ import print_function

from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 5, 0.1)
y = np.sin(x)
# figure creation by plt (also given a manager, although not explicitly)
plt.figure()
plt.plot(x,y)
coords = plt.ginput() # click on the axes somewhere; this works
print(coords)

# figure creation w/o plt
manualfig = Figure()
manualaxes = manualfig.add_subplot(111)
manualaxes.plot(x,y)
manualfig.show() # will fail because of no manager, yet shown as a method
manualcoords = manualfig.ginput() # comment out above and this fails too
print(manualcoords)

As popular as pyplot is (I can't hardly find an answer without it), it doesn't seem to play nice when working with a GUI. I thought pyplot was simply a wrapper for the OO framework but I guess I'm just a noob.

My question then is this: Is there some way to attach pyplot to an instance of matplotlib.figure.Figure? Is there an easy way to attach a manager to a Figure? I found new_figure_manager() in matplotlib.backends.backend_qt4agg, but couldn't get it to work, even if it is the right solution.

Many thanks,

James

Community
  • 1
  • 1
James
  • 437
  • 1
  • 6
  • 16
  • You wanna handle the button click event? – zhangxaochen Mar 06 '14 at 07:05
  • Specifically, yes; I worked around this with a canvas.connect() to the button press although it didn't help my understanding. Generally, I'd like my embedded matplotlib widget to have the methods pyplot has (gingput, etc). – James Mar 06 '14 at 17:22

1 Answers1

2

pyplot is just a wrapper for the OO interface, but it does a lot of work for you read the example you link to again carefully, the

FigureCanvas.__init__(self, fig)

line is very important as that is what tells the figure what canvas to use. The Figure object is just a collection of Axes objects (and a few Text objects), the canvas object is what knows how to turn Artist objects (ie matplotlib's internal representation of lines, text, points, etc) in to pretty colors. Also see something I wrote for another embedding example which does not sub-class FigureCanvas.

There is a PR to make this process easier, but it is stalled while we get 1.4 out the door.

also see: Which is the recommended way to plot: matplotlib or pylab?, How can I attach a pyplot function to a figure instance?

Community
  • 1
  • 1
tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • I understand about the FigureCanvas; that makes sense. I think I'm circling the solution, I just haven't gotten there =) I'll look at your work, thanks! – James Mar 06 '14 at 17:18