Introduction
Sur Ubuntu, un script Python 3 exécutant Matplotlib pour afficher un graphique échoue avec l’erreur ci-dessous :
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()
L’erreur se produit dans un environnement virtuel Python 3.9 virtual environment. L’installation du package Matplotlib dans l’environnement virtuel a été réalisée sans encombres.
$ pip3 list
Package Version --------------- ------- matplotlib 3.4.2
Quel est le problème et comment le résoudre ?
Diagnostic du problème
La fonction get_backend
du package matplotlib
donne la réponse :
import matplotlib matplotlib.get_backend()
'agg'
Pour afficher la figure, matplotlib
a besoin d’un "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
n’est pas un GUI backend.
Pour utiliser le GUI backend Tcl/Tk (TkAgg
), Python a besoin du module tkinter
.
Si l’import échoue, la distribution Python n’est pas configurée correctement.
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'
Configuration de Python avec Tcl Tk
Distribution Python personnalisée (compilée)
Si la distribution source Python utilisée pour construire l’environnement virtuel a été compilée avec Tcl/Tk absent de la machine, pas le choix :
- Une nouvelle distribution source Python est compilée avec Tcl/Tk installé.
- L’environnement virtuel est reconstruit avec cette nouvelle distribution source Python.
1. Installer Tcl/Tk :
$ apt-get install tcl-dev tk-dev
2. Compiler la nouvelle distribution source Python. Tcl/Tk est installé, le module tkinter
sera construit :
$ ./configure --prefix=/opt/python/python-3.9.5 \
--enable-optimizations \
--with-system-ffi \
--enable-ipv6
$ make
$ make install
3. On peut vérifier que tkinter
a été construit pour Python avec
l’existence du fichier _tkinter.cpython-39-x86_64-linux-gnu.so
dans le répertoire <installation dir Python 3.9>/lib/python3.9/lib-dynload/
.
Remplacer 39 et 3.9 par 3x et 3.x pour toute version Python 3.x.
4. L’environnement virtuel est reconstruit, matplotlib
installé.
Quand matplotlib
est installé dans l’environnement virtuel,
la librairie backend TkAgg
correspondante est compilée : <dir virtual env>/lib/python3.9/site-packages/matplotlib/backends/_tkagg.cpython-39-x86_64-linux-gnu.so
.
Distribution Python par défaut
Si le problème ne survient pas dans une distribution Python personnalisée, ni dans un environnement virtuel :
- installer
Tcl/Tk
puispython-tk
(Python 2) oupython3-tk
(Python 3) selon la version de Python utilisée$ apt-get install tcl-dev tk-dev python-tk python3-tk
- réinstaller
matplotlib
avecpip
$ pip3 --no-cache-dir install -U --force-reinstall matplotlib
Comme pour les distributions personnalisées Python, les librairies nécessaires sont compilées/installées :
/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
Affichage de la figure matplotlib
Maintenant, le module tkinter
peut être chargé et le backend GUI de matplotlib
est le bon :
import tkinter import matplotlib matplotlib.get_backend()
'TkAgg'
La figure est correctement affichée avec la redirection X11 (SQLPAC - Ubuntu, afficher des fenêtres serveur X vers des hôtes clients Windows 10 avec Putty et XMing Server), no particular issue.