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

197

J'exécute un simple script python 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.pydans ce serveur sur lequel matplotlib 1.5.1 est installé, elle échoue avec l'erreur:

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?

user3654307
la source
10
Exécutez-vous cela sur ssh?
Padraic Cunningham
8
... sans -X?
Klaus D.
1
Si vous l'exécutez sur le notebook Jupyter, exécutez cette commande sur le notebook%matplotlib inline
GoingMyWay
Si vous vous connectez de la machine Win au serveur distant via putty, vous devez installer Xming pour transférer X11.
Serenity

Réponses:

297

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 réessayez:

import matplotlib
matplotlib.use('Agg')

Ou ajoutez à la .config/matplotlib/matplotlibrcligne backend: Aggpour utiliser un backend non interactif.

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

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

Aussi , vous pouvez essayer d'affichage à l'exportation: export DISPLAY=mymachine.com:0.0.

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

Sérénité
la source
13
'ssh -X remoteMachine' a résolu mon problème. Je vous remercie!
user3654307
6
qu'est-ce que «Agg» en fait?
CKM
5
AGG est l'abréviation de Anti-grain geometry engine.
Serenity
5
matplotlib.use('Agg')fonctionne pour moi - s'exécutant dans une image Docker.
Mattia Paterna
Celui-ci a résolu mon problème. J'exécute sur des VM cloud Google, j'espère que cela aidera les gens à avoir le même problème.
Démo du
76

Vous pouvez le résoudre en ajoutant ces deux lignes au TRÈS début 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.

Qihui
la source
17
Il devrait au tout début du code. C'est important.
chasseur le
cela a fonctionné lors de l'exécution matplotlibsur le docker (pas d'affichage attaché), mais que fait-il réellement?
loretoparisi
Cela fonctionne pour moi lorsque j'exécute simplement la console python sur ma machine virtuelle, mais le même code échoue avec exactement la même erreur sur la même machine virtuelle lorsqu'elle fait partie de l'application en cours d'exécution.
rschwieb
Mais changer le backend de TkAgg à Agg dans le fichier de configuration a fait l'affaire.
rschwieb
42

Pour ajouter la réponse, j'ai utilisé ceci au début du script nécessaire. Il fonctionne donc sans problème 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 'Agg'backend, uniquement quand il passerait par Travis CI par exemple.

Sylhare
la source
4
Cette solution a la valeur ajoutée d'être la moins intrusive quelle que soit sa configuration personnelle. Cela devrait être plus élevé.
jaumebonet
11

J'ai eu ce même problème en essayant d'exécuter une simple application tkinter à distance sur un Raspberry Pi. Dans mon cas, je voulais afficher l'interface graphique de tkinter sur l'écran pi, mais je veux pouvoir l'exécuter via SSH à partir de ma machine hôte. Je n'utilisais pas non plus matplotlib, donc ce n'était 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: /ubuntu/432255/what-is-display-environment-variable

ajgriese
la source
18
J'essaie de sauvegarder des parcelles avec python et matplotlib.pyplot fonctionnant sur ssh ... cela me donne: _tkinter.TclError: impossible de se connecter pour afficher ": 0.0"
mrk
2

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

$ ./example.py

Joseph
la source
1

J'ai également rencontré ce problème en utilisant 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 ci-dessus ne peuvent pas résoudre votre problème, essayez simplement de télécharger Xming sous la condition que vous utilisez Xshell. Ensuite, définissez l'attribut dans Xshell, SSH-> tunnel-> X11transfer-> choisissez X DISPLAY localhost: 0.0

Mode
la source
1

Pour voir les images, les tracés et tout ce qui est affiché sur les fenêtres de votre machine distante, vous devez vous y connecter comme ceci:

ssh -X user@hostname

De cette façon, vous activez l'accès au serveur X. Le serveur X est un programme du système X Window qui s'exécute sur des machines locales (c'est-à-dire les ordinateurs utilisés directement par les utilisateurs) et gère tous les accès aux cartes graphiques, aux écrans d'affichage et aux périphériques d'entrée (généralement un clavier et une souris) sur ces ordinateurs .

Plus d'infos ici .

tsveti_iko
la source