Introduction
On Ubuntu, a Python 3 script running Matplotlib to display a graph fails with the following error :
import matplotlib.pyplot as plt plt.plot([1, 2, 3, 4]) plt.ylabel('some numbers') plt.show()myplot.py:4: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. plt.show()
The error occurs in a Python 3.8 virtual environment. The installation of the Matplotlib package in the virtual environment was successful.
$ pip3 listPackage Version --------------- ------- matplotlib 3.4.2
What’s the issue and how to solve it ?
Diagnosing the issue
The function get_backend of the package matplotlib gives the answer :
import matplotlib matplotlib.get_backend()'agg'
To display the figure, matplotlib needs a GUI backend : Tcl Tk (TkAgg), Qt 4/5 (Qt4Agg, Qt5Agg)…
import matplotlib.rcsetup as rcsetup print(rcsetup.all_backends)['GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg', 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo', 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo', 'agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template']
agg is not a GUI backend.
To use the Tcl Tk GUI backend (TkAgg), Python needs the module tkinter. If the import fails, Python distribution
is not configured properly.
import tkinterFile "/opt/python/python-3.8/lib/python3.8/tkinter/__init__.py", line 36, in <module> import _tkinter # If this fails your Python may not be configured for Tk ModuleNotFoundError: No module named '_tkinter'
Configuring Python with Tcl Tk
Customized Python distribution (compiled)
If the Python source distribution to build the virtual environment was compiled with Tcl/Tk missing on the host, no choice :
- A new Python source distribution is compiled with Tcl/Tk installed.
- The virtual environment is rebuilt with the updated Python source distribution.
1. Install Tcl/Tk :
$ apt-get install tcl-dev tk-dev
2. Compile the new Python source distribution. Tcl/Tk is installed, the tkinter module will be built :
$ ./configure --prefix=/opt/python/python-3.9.5 \
--enable-optimizations \
--with-system-ffi \
--enable-ipv6
$ make
$ make install
3. You can verify that tkinter has been built for Python by checking
the existence of the file _tkinter.cpython-39-x86_64-linux-gnu.so
in the directory <installation dir Python 3.9>/lib/python3.9/lib-dynload/ for Python 3.9.
Replace 39 and 3.9 by 3x and 3.x for any Python 3.x version.
4. The virtual environment is rebuilt, matplotlib installed.
When matplotlib is installed in the virtual environment,
the matching TkAgg backend library is compiled : <dir virtual env>/lib/python3.9/site-packages/matplotlib/backends/_tkagg.cpython-39-x86_64-linux-gnu.so.
Default Python distribution
If the issue does not occur in a customized Python distribution, nor virtual environment :
- install
Tcl/Tkand thenpython-tk(Python 2) orpython3-tk(Python 3) depending on the used Python version$ apt-get install tcl-dev tk-dev python-tk python3-tk - reinstall
matplotlibusingpip$ pip3 --no-cache-dir install -U --force-reinstall matplotlib
As with custom Python distributions, needed libraries are compiled/installed :
/usr/lib/python3.6/lib-dynload/_tkinter.cpython-36m-x86_64-linux-gnu.so/usr/lib/python3.6/site-packages//matplotlib/backends/_tkagg.cpython-39-x86_64-linux-gnu.so
Running the matplotlib figure
Now, the tkinter module can be loaded and the matplotlib GUI backend is the right one :
import tkinter import matplotlib matplotlib.get_backend()'TkAgg'
The figure is well displayed using X11 forwarding (SQLPAC - Ubuntu, how to display server windows on Windows 10 client hosts with Putty and XMing Server), no particular issue.