web-dev-qa-db-fra.com

_tkinter.TclError: pas de nom d'affichage ni de variable d'environnement $ DISPLAY

J'exécute un script python simple sur le serveur:

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randn(60)
y = np.random.randn(60)

plt.scatter(x, y, s=20)

out_png = 'path/to/store/out_file.png'
plt.savefig(out_png, dpi=150)

J'essaie d'utiliser la commande python example.py sur ce serveur sur lequel matplotlib 1.5.1 est installé. Il échoue avec l'erreur suivante:

Traceback (most recent call last):
  File "example.py", line 7, in <module>
    plt.scatter(x, y, s=20)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 3241, in scatter
    ax = gca()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 928, in gca
    return gcf().gca(**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 578, in gcf
    return figure()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 527, in figure
**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 84, in new_figure_manager
    return new_figure_manager_given_figure(num, figure)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 92, in new_figure_manager_given_figure
    window = Tk.Tk()
  File "/usr/local/lib/python2.7/lib-tk/Tkinter.py", line 1810, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

Que se passe-t-il ici?

149
user3654307

Matplotlib choisit le backend Xwindows par défaut. Vous devez configurer matplotlib pour ne pas utiliser le backend Xwindows.

Ajoutez ce code au début de votre script ( avant d'importer pyplot ) et essayez à nouveau:

import matplotlib
matplotlib.use('Agg')

Ou ajoutez à la .config/matplotlib/matplotlibrc line backend: Agg pour utiliser un backend non interactif.

echo "backend: Agg" > ~/.config/matplotlib/matplotlibrc

Ou lorsque vous vous connectez au serveur, utilisez la commande ssh -X remoteMachine pour utiliser Xwindows.

Aussi, vous pouvez essayer d’afficher: export DISPLAY=mymachine.com:0.0.

Pour plus d'informations: https://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server

237
Serenity

Vous pouvez le résoudre en ajoutant ces deux lignes dans le début VERY de votre script .py.

import matplotlib
matplotlib.use('Agg')

PS: L'erreur existera toujours si ces deux lignes ne sont pas ajoutées au tout début du code source.

61
Qihui

Pour ajouter la réponse, j'ai utilisé cela au début du script requis. Donc, il fonctionne bien sur différents environnements.

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using non-interactive Agg backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt

Parce que je ne voulais pas qu'il utilise toujours le backend 'Agg', uniquement lorsqu'il passe par Travis CI par exemple.

28
Sylhare

J'ai eu le même problème en essayant de lancer une simple application tkinter à distance sur un Raspberry Pi. Dans mon cas, je voulais afficher l'interface graphique de tkinter sur l'affichage de pi, mais je veux pouvoir l'exécuter sur SSH à partir de ma machine hôte. Je n'utilisais pas non plus matplotlib, ce n'était donc pas la cause de mon problème. J'ai pu résoudre le problème en définissant la variable d'environnement DISPLAY comme le suggère l'erreur avec la commande:

export DISPLAY=:0.0

Une bonne explication de ce que fait la variable d'environnement d'affichage et pourquoi la syntaxe est si étrange peut être trouvée ici: https://askubuntu.com/questions/432255/what-is-display-environment-variable =

6
ajgriese

Une autre solution consiste à installer Xvfb et à y exporter votre affichage. c'est à dire:

disp=:8
screen=0
geom=640x480x24
exec Xvfb $disp -screen $screen $geom 2>/tmp/Xvfb.log &

Ensuite

$ export DISPLAY =: 8

$ ./exemple.py

1
Joseph

J'ai également rencontré ce problème lors de l'utilisation de Xshell pour connecter un serveur Linux.

Après avoir recherché des méthodes, je trouve Xming + Xshell pour résoudre le problème d’image imshow avec matplotlib.

Si les solutions décrites ci-dessus ne permettent pas de résoudre votre problème, essayez simplement de télécharger Xming sous la condition que vous utilisez Xshell. Puis définissez l'attribut dans Xshell, SSH-> tunnel-> X11transfer-> choisissez X DISPLAY localhost: 0.

1
Mode