Reputation: 5746
I am trying to get user selected points (to get a polygon) from an image. I have already embedded a matplotlib.figure in a lot of my code, so I would MUCH prefer to use this style over pylab's figure. I am trying to do the follow:
import pylab
from matplotlib.figure import Figure
x1 = pylab.rand(103, 53)
figure = Figure(figsize=(4, 4), dpi=100)
axes = figure.add_subplot(111)
axes.imshow(x1)
x = figure.ginput(2)
print(x)
But I get the following error:
Traceback (most recent call last):
File "ginput_demo.py", line 17, in <module>
x = figure.ginput(2)
File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 1177, in ginpu
t
show_clicks=show_clicks)
File "C:\Python27\lib\site-packages\matplotlib\blocking_input.py", line 282, i
n __call__
BlockingInput.__call__(self,n=n,timeout=timeout)
File "C:\Python27\lib\site-packages\matplotlib\blocking_input.py", line 94, in
__call__
self.fig.show()
AttributeError: 'Figure' object has no attribute 'show'
The original pylab code that works that I am trying to more or less reproduce is from here:
import pylab
x1 = pylab.rand(103, 53)
fig1 = pylab.figure(1)
ax1 = fig1.add_subplot(111)
ax1.imshow(x1)
ax1.axis('image')
ax1.axis('off')
x = fig1.ginput(2)
fig1.show()
So basically, is there a way to get pylab.ginput to work with a matplotlib.figure or matplotlib.axes reference??
Thanks,
tylerthemiler
Upvotes: 3
Views: 2976
Reputation: 1
I couldn't get the suggested solution to work properly when using an embedded plot in a GUI (Pyqt4) - my quick&dirty working solution was to put a Try/Catch into blocking_input.py. Note -this would probably be overwritten when you update matplotlib so you may want to save associations using unique name(s)
# TRY TO "Ensure that the figure is shown" in the standard way
try:
self.fig.show()
except AttributeError:
pass
Upvotes: 0
Reputation: 85613
You should use pylab.ginput
instead of myfigure.ginput
.
After changing this, you will realize that axes.imshow
is not plotting, you can fix it using pylab.imshow
.
And finally you will find that after clicking and getting the position numbers, the figure disappears, so you want to add a pylab.show
at the end.
This works, trying to follow as close as possible your prefered way of coding mpl:
from pylab import show, ginput, rand, imshow
from matplotlib.figure import Figure
x1 = rand(103, 53)
figure = Figure(figsize=(4, 4), dpi=100)
axes = figure.add_subplot(111)
imshow(x1)
x = ginput(2)
print(x)
show()
I think the problem here comes from mixing different modules (coding styles) from matplotlib.
Your myfigure.ginput()
complaints about its Figure class not having a show
method. However it works with pylab.figure.ginput()
.
In fact, pylab.figure
, that is actually the one defined in the pyplot module:
>>> import pylab
>>> import matplotlib.pyplot as plt
>>> pylab.figure is plt.figure
True
although being of the class matplotlib.figure.Figure
is not the same as the Figure instance
myfigure = matplotlib.figure.Figure()
pyplot.figure
implements a couple of additional methods, one of them show()
:
>>> from matplotlib import pyplot
>>> from matplotlib.figure import Figure
>>> pfig = set(dir(pyplot.figure()))
>>> Ffig = set(dir(Figure()))
>>> pfig.difference(Ffig)
set(['number', 'show'])
that's why you got the AttributeError
with the Figure
instance.
Upvotes: 3