当我尝试创建Matplotlib按钮时,我收到了一个神秘的错误。
我有一个类,它有许多Matplotlib轴作为实例属性。我正在通过以下调用实例化该按钮:
Button(self.energy_diagram, 'Show Attractors')
我收到以下错误:
Traceback (most recent call last):
File "ocr.py", line 20, in <module>
myNet.run_visualization(training_data, learning_data)
File "/home/daniel/Documents/coding/visuals.py", line 93, in run_visualization
self._plot_energy()
File "/home/daniel/Documents/coding/visuals.py", line 235, in _plot_energy
Button(self.energy_diagram, 'Show Attractors')
File "/usr/local/lib/python3.4/dist-packages/matplotlib/widgets.py", line 191, in __init__
transform=ax.transAxes)
TypeError: text() missing 1 required positional argument: 's'
有趣的是,如果我将它添加到我的图中的其他轴上,Button会起作用,而self.energy_diagram
轴是唯一的3d,所以我想知道它是否与它有关
非常感谢任何帮助!
答案 0 :(得分:1)
首先,您的错误消息。这很令人惊讶,但相当清楚。你关于有问题的轴是唯一的3d的说明是关键。有和没有错误的两个最小例子:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.widgets as widgets
hf1,ha1 = plt.subplots()
ha1.plot([1,2,3],[4,5,6])
butt1 = widgets.Button(ha1,'button 1') # <-- works great
hf2 = plt.figure()
ha2 = hf2.add_subplot(111,projection='3d')
ha2.plot([1,2,3],[4,5,6],[7,8,9])
butt2 = widgets.Button(ha2,'button 2') # <-- error
首先,看一下第191行的/usr/local/lib/python3.4/dist-packages/matplotlibwidgets.py:
class Button(AxesWidget):
def __init__(self, ax, label, image=None,
color='0.85', hovercolor='0.95'):
AxesWidget.__init__(self, ax)
if image is not None:
ax.imshow(image)
self.label = ax.text(0.5, 0.5, label,
verticalalignment='center',
horizontalalignment='center',
transform=ax.transAxes) # <-- line 191
该按钮尝试调用正在放入text
的{{1}}方法,此调用产生错误。使用Axes
help
(ha1.text
的绑定版本):
matplotlib.pyplot.Axes.text
text(x, y, s, fontdict=None, withdash=False, **kwargs) method of matplotlib.axes._subplots.AxesSubplot instance
Add text to the axes.
Add text in string `s` to axis at location `x`, `y`, data
coordinates.
(ha2.text
的绑定版本)相同:
mpl_toolkits.mplot3d.Axes3D.text
发现差异:后者函数也必须接收text(x, y, z, s, zdir=None, **kwargs) method of matplotlib.axes._subplots.Axes3DSubplot instance
Add text to the plot. kwargs will be passed on to Axes.text,
except for the `zdir` keyword, which sets the direction to be
used as the z direction.
坐标,以便将文本放在3d轴上。说得通。 z
小部件根本不适用于3d轴。
现在,你可以尝试自己解决这个问题,虽然Button
明显缺乏3D轴支持的事实表明你迟早会用脚射击自己。无论如何,你可以通过用Button
的{{1}}方法覆盖text
方法来解决错误,并进行一些调整以将ha2
放在正确的位置。再说一遍,我并不是说这不能随时打破任何事情,也不这样做是可怕的事情,但它是一个选择:
ha1
对于它的价值,它现在看起来和2d版本一样糟糕:
这引出了我的最后一点。据我所知,小部件会自动占据他们所投入的整个轴。 不将小部件(一个固有的2d对象)放入3d轴似乎是合理的:您希望它如何定位?显而易见的解决方案是将每个小部件存储在其自己的轴上,在其他GUI组件和图形的顶部/旁边。这样,您可以自然地为每个小部件使用2D轴。我相信这是这样做的标准方法,这可以解释为什么没有明确提到不支持3d轴。他们为什么会这样?