从 Matplotlib 工具栏中删除"help"工具会导致:属性错误:'NoneType'对象没有属性'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.04Microsoft托管的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'

这在ubuntu-18.04Azure VM上的Python 3.6.12和3.7.9中都会发生。两者都在使用matplotlib 3.3.1。

然而,在Windows中,在Python 3.6.8和3.7.9中的windows-2019Microsoft托管虚拟机上,以及在matplotlib 3.3.1上,相同的代码运行时没有出现错误。

有没有其他人看到了这一点,并找到了解决方案或变通方法?不幸的是,我无法在我自己的ubuntu虚拟机上复制它。

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

2020年9月2日更新

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

那么,我需要为Linux中的matplotlib做一些额外的事情吗?Azure使用的18.04 ubuntu虚拟机上的软件包在这里列出,如果有帮助的话,包括这些:

  • libgtk-3-0
  • tk

2021年8月5日更新

运行这个修复了我自己的ubuntu虚拟机中的问题:

$ sudo apt-get install python3-tk 

我认为它安装了Tcl/Tk的后端库(请参阅此处(。但不幸的是,此修复程序无法修复ubuntu-18.04Azure 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()

事实证明,除非虚拟显示服务器(如Xvfb(在后台运行,否则Tcl/Tk不会在ubuntu Azure DevOps虚拟机上工作。您还需要将DISPLAY环境变量设置为指向此显示。有关详细信息,请参阅此处的相关答案。

最新更新