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

In my ubuntu 18.04 VM with Python 3.7.7 and matplotlib 3.3.1 this code works without error:

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

But when the same code is called from a unittest in my Azure DevOps build pipeline, it fails at tm.remove_tool('help') on the ubuntu-18.04 Microsoft-hosted VM with:

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'

This happens in both Python 3.6.12 and 3.7.9 on the ubuntu-18.04 Azure VM. Both are using matplotlib 3.3.1 as well.

However the same code runs without error in Windows on a windows-2019 Microsoft-hosted VM in both Python 3.6.8 and 3.7.9, also both on matplotlib 3.3.1.

Has anyone else seen this and got a fix or workaround please? Unfortunately I can't reproduce this on my own ubuntu VM.

Maybe the Microsoft-hosted ubuntu-18.04 VM is missing something matplotlib needs? Or there's a weird matplotlib bug? I didn't see this issue in Azure when I was on matplotlib 3.1.1.

Update on 2 Sept 2020

After adding the line print("Tools: %s" % tm._tools) after initialising tm I find that tm._tools is a dict with many entries on Windows in Azure (and tm._tools['help'] is a matplotlib.backends._backend_tk.HelpTk object). But in Linux on Azure tm._tools is an empty dict: {}!

So do I need to do something extra for matplotlib in Linux? The packages on the 18.04 ubuntu VM used by Azure are listed here and include these, if it helps:

  • libgtk-3-0
  • tk

Update on 5 Aug 2021

Running this fixes the issue in my own ubuntu VM:

$ sudo apt-get install python3-tk 

I think it installs the back-end libraries for Tcl/Tk (see here). But unfortunately this fix does not cure the error in the ubuntu-18.04 Azure VM.



Solution 1:[1]

It turns out Tcl/Tk won't work on an ubuntu Azure DevOps VM unless a virtual display server is running in the background, such as Xvfb. You also need to set the DISPLAY environment variable to point at this display. See my related answer here for details.

Solution 2:[2]

I don't have an answer as to why Azure is doing this sadly. Though, as a workaround you could always explore plotting the figure without the toolbar, depending on your needs.

something like:

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()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 snark
Solution 2 Gibus