来自matplotlib的TypeError按钮实例化

时间:2016-06-02 17:58:04

标签: python python-3.x matplotlib

当我尝试创建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,所以我想知道它是否与它有关

非常感谢任何帮助!

1 个答案:

答案 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 helpha1.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 version bad bad ugly 3d version

这引出了我的最后一点。据我所知,小部件会自动占据他们所投入的整个轴。 将小部件(一个固有的2d对象)放入3d轴似乎是合理的:您希望它如何定位?显而易见的解决方案是将每个小部件存储在其自己的轴上,在其他GUI组件和图形的顶部/旁边。这样,您可以自然地为每个小部件使用2D轴。我相信这是这样做的标准方法,这可以解释为什么没有明确提到不支持3d轴。他们为什么会这样?