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 list
Package 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 tkinter
File "/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/Tk
and 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
matplotlib
usingpip
$ 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.