Removing "help" tool from Matplotlib toolbar causes: AttributeError: 'NoneType' object has no attribute 'destroy'

Removing "help" tool from Matplotlib toolbar causes: AttributeError: 'NoneType' object has no attribute 'destroy'

在我的 ubuntu 18.04 VM 中,Python 3.7.7 和 matplotlib 3.3.1 此代码运行无误:

    plt.rcParams['toolbar'] = 'toolmanager'
    fig = plt.figure()
    tm = fig.canvas.manager.toolmanager
    tm.remove_tool('help') # Fails here in ubuntu in Azure!

但是当从我的 Azure DevOps 构建管道中的单元测试调用相同的代码时,它在 ubuntu-18.04 Microsoft 托管的 VM 上的 tm.remove_tool('help') 处失败:

File "/opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/site-packages/matplotlib/backend_managers.py", line 228, in remove_tool
    tool.destroy()
AttributeError: 'NoneType' object has no attribute 'destroy'

Python Azure VM 上的 Python 3.6.12 和 3.7.9 都会发生这种情况。两者都在使用 matplotlib 3.3.1。

然而,相同的代码在 Windows 中 windows-2019 Microsoft 托管的 VM 中 Python 3.6.8 和 3.7.9 以及 matplotlib 3.3 中都可以正常运行。 1.

请问有没有其他人看到这个问题并得到修复或解决方法?不幸的是,我无法在自己的 ubuntu VM 上重现此内容。

也许 Microsoft 托管的 ubuntu-18.04 虚拟机缺少 matplotlib 需要的东西?或者有一个奇怪的 matplotlib 错误?当我在 matplotlib 3.1.1 上时,我在 Azure 中没有看到这个问题。

2020 年 9 月 2 日更新

在初始化 tm 后添加行 print("Tools: %s" % tm._tools) 之后,我发现 tm._tools 是一个在 Azure 中的 Windows 上有许多条目的字典(和 tm._tools['help']是一个 matplotlib.backends._backend_tk.HelpTk 对象)。但是在 Azure 上的 Linux 中 tm._tools 是一个空字典:{}!

所以我需要为 Linux 中的 matplotlib 做一些额外的事情吗?列出了 Azure 使用的 18.04 ubuntu VM 上的包 here 并包括这些包,如果有帮助的话:

2021 年 8 月 5 日更新

运行 这解决了我自己 ubuntu VM 中的问题:

$ sudo apt-get install python3-tk 

我认为它安装了 Tcl/Tk 的后端库(参见 here)。但不幸的是,此修复程序无法解决 ubuntu-18.04 Azure VM 中的错误。

对于 Azure 为何如此悲哀,我没有答案。 不过,作为一种解决方法,您始终可以根据需要探索在没有工具栏的情况下绘制图形。

类似于:

import tkinter as tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

data = [i for i in range(5)]

window = tk.Tk()

artist = Figure()
artist.add_subplot().plot(data)
canvas = FigureCanvasTkAgg(artist, master=window)
canvas.draw()
canvas.get_tk_widget().pack()

window.mainloop()

事实证明 Tcl/Tk 无法在 ubuntu Azure DevOps VM 上运行,除非虚拟显示服务器 运行 在后台,例如 Xvfb。您还需要设置 DISPLAY 环境变量以指向此显示。详情见我的相关回答