matplotlib按钮实例化的TypeError

2024-05-18 05:38:03 发布

您现在位置:Python中文网/ 问答频道 /正文

当我试图创建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'

有趣的是,如果我将它添加到我的图形中的其他轴上,按钮就会工作,self.energy_diagram轴是唯一一个3d轴,所以我想知道这是否与此有关。你知道吗

任何帮助都将不胜感激!你知道吗


Tags: 实例runinpyselfmatplotlibshow错误
1条回答
网友
1楼 · 发布于 2024-05-18 05:38:03

首先,你的错误信息。这很令人惊讶,但相当清楚。你关于有问题的轴是唯一的三维轴的注释是关键。有无错误的两个最小示例:

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

首先,看一下/usr/local/lib/python3.4/dist-packages/matplotlibwidgets.py文件,在191行附近:

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

这个按钮试图调用它被放入的Axestext方法,这个调用产生了错误。使用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.

找出区别:后一个函数也必须接收z坐标,以便将文本放置在3d轴上。有道理。Button小部件并不是设计用来处理3d轴的。你知道吗

现在,您可以尝试自己解决这个问题,尽管Button显然缺乏3d轴支持这一事实表明,您迟早会向自己的脚开枪。无论如何,您实际上可以通过用ha1的方法覆盖ha2text方法来消除错误,并进行一些调整以将self放在正确的位置。再说一次,我不是说这不能打破任何东西,也不是说这是可怕的事情,但这是一个选择:

hf2 = plt.figure()
ha2 = hf2.add_subplot(111,projection='3d')
ha2.plot([1,2,3],[4,5,6],[7,8,9])
ha2.text = lambda x,y,s,self=ha2,**kwargs : plt.Axes.text(self,x,y,s,kwargs)
butt2 = widgets.Button(ha2,'button 2')     # <  no error

值得一提的是,它现在看起来和2d版本一样糟糕:

2d versionbad bad ugly 3d version

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

相关问题 更多 >