使用ginput时,matplotlib.figure与pylab的错误

3 投票
2 回答
2948 浏览
提问于 2025-04-17 09:04

我正在尝试从一张图片中获取用户选择的点,以便形成一个多边形。我已经在很多代码中嵌入了matplotlib.figure,所以我更希望使用这种方式,而不是pylab的图形。我想要做的是:

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)

但是我遇到了以下错误:

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'

我想要大致复现的原始pylab代码来自于 这里

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() 

所以基本上,有没有办法让pylab.ginput与matplotlib.figure或matplotlib.axes一起工作呢?

谢谢,

tylerthemiler

2 个回答

0

我在使用嵌入式图表的图形界面(Pyqt4)时,没能让推荐的解决方案正常工作。于是我快速找了个简单的办法,就是在blocking_input.py里加了一个Try/Catch的代码。需要注意的是,当你更新matplotlib的时候,这个修改可能会被覆盖,所以你可能需要用独特的名字来保存相关的设置。

 # TRY TO "Ensure that the figure is shown" in the standard way
    try:
        self.fig.show()
    except AttributeError:
        pass
3

你应该使用 pylab.ginput 而不是 myfigure.ginput。这样改了之后,你会发现 axes.imshow 没有绘图,这时可以用 pylab.imshow 来解决这个问题。最后,你会发现点击获取位置坐标后,图形消失了,所以你需要在最后加一个 pylab.show

这样做是有效的,尽量按照你喜欢的方式来写 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()

我觉得问题出在混用了 matplotlib 的不同模块(编码风格)。
你的 myfigure.ginput() 报错是因为它的 Figure 类没有 show 方法。不过,pylab.figure.ginput() 是可以正常工作的。
实际上,pylab.figure 是在 pyplot 模块中定义的:

>>> import pylab
>>> import matplotlib.pyplot as plt 
>>> pylab.figure is plt.figure
True

虽然它是 matplotlib.figure.Figure 类的,但并不等同于 Figure 实例。

myfigure = matplotlib.figure.Figure()

pyplot.figure 实现了一些额外的方法,其中一个就是 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'])

这就是你在 Figure 实例中遇到 AttributeError 的原因。

撰写回答