DISPLAY अपरिभाषित होने पर matplotlib के साथ PNG बनाना


319

मैं पायथन के साथ नेटवर्कएक्स का उपयोग करने की कोशिश कर रहा हूं। जब मैं इस प्रोग्राम को चलाता हूं तो यह त्रुटि मिलती है। क्या कुछ छूट गया है?

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")


Traceback (most recent call last):
  File "graph.py", line 13, in <module>
    nx.draw(G)
  File "/usr/lib/pymodules/python2.5/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

मुझे अब एक अलग त्रुटि मिलती है:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in <module>
    nx.draw(G)
  File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

मुझे अब एक अलग त्रुटि मिलती है:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in <module>
    nx.draw(G)
  File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable


9
अपने अन्य आयातों के ऊपर कॉल को matplotlib.use ('Agg') पर ले जाएँ, विशेष रूप से यह matplotlib.pyplot
Ivo Bosticky

@IvoBosticky टिप्पणी ने इसे मेरे लिए भी हल कर दिया: केवल एक चीज जो भ्रामक है "आपके अन्य आयातों के ऊपर"। यह स्पष्ट होना चाहिए कि आपको पहले matplotlib आयात करने की आवश्यकता है ... यह मेरे लिए काम करने वाली पूरी सेटिंग है: matplotlib // matplotlib.use ('Agg') आयात करें: plt
mrk

जवाबों:


518

मुख्य समस्या यह है कि (आपके सिस्टम पर) matplotlib डिफ़ॉल्ट रूप से एक एक्स-उपयोग बैकएंड चुनता है। मुझे अपने सर्वर में एक ही समस्या थी। मेरे लिए समाधान निम्नलिखित कोड को किसी अन्य पाइलैब / matplotlib / pyplot आयात से पहले पढ़ने के लिए मिलता है।

import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')

विकल्प इसे अपने .matplotlibrc में सेट करना है


182
महत्वपूर्ण नोट:। Pyplot को आयात करने से पहले .use को बुलाया जाना चाहिए। उदाहरण के लिए, यदि आप उदाहरण के लिए, बस pyplot आयात करने की कोशिश कर रहे हैं, तो आपको पहले matplotlib आयात करना होगा, कॉल उपयोग करना चाहिए, और pyplot आयात करना चाहिए।
सीओटर्नटेरड

8
उपरोक्त टिप्पणी को इस उत्तर द्वारा और अधिक समझाया गया है ।
Ioannis Filippidis

2
आप इसे "अपने .matplotlibrc" में कैसे सेट करते हैं?
tommy.carstensen

18
backend: aggin ~/.config/matplotlib'/matplotlibrc(उदाहरण के लिए, Seehttp: //matplotlib.org/faq/troublesourcing_faq.html#locating-matplotlib-config-dir)। Matplotlib.org/users/customizing.html भी देखें , जिसमें पृष्ठ के निचले भाग में एक उदाहरण कॉन्फ़िगर फ़ाइल है। उस पृष्ठ पर "agg" ढूंढें और आपको वह विन्यास विकल्प दिखाई देगा जिसकी आपको आवश्यकता है।
रीइनआउट वैन रीस

4
संदर्भ के लिए, यहाँ matplotlib प्रलेखन की कड़ी है जो इसे समझाता है। (+1, बढ़िया जवाब, मेरी पूरी तरह से मदद करता है!)
टिम एस।

72

रेनॉउट के उत्तर के पूरक के रूप में।

इस तरह की समस्या को हल करने का स्थायी तरीका .matplotlibrc फ़ाइल को संपादित करना है। इसके माध्यम से खोजें

>>> import matplotlib
>>> matplotlib.matplotlib_fname() # This is the file location in Ubuntu '/etc/matplotlibrc'

फिर उस फ़ाइल में बैकएंड को संशोधित करें backend : Agg। बस इतना ही।


5
प्रो टिप: $MATPLOTLIBRCउस डायरेक्टरी पर सेट करें, जहाँ आप अपना मैटप्लोटब्रिस्क फेंकना चाहते हैं।
केनेथ होस्ट

Kinda इस तरह की समस्या के लिए ओवरक्लिल करता है, लेकिन मुझे लगता है कि अगर सर्वर हमेशा हेडलेस काम कर रहा है तो यह कॉन्फ़िगरेशन फाइल को संशोधित करने के लिए समझ में आता है। क्या इसका कोई दुष्प्रभाव होगा कि कैसे matplotlib कार्य करेगा?
ब्रूसजॉनजेनरलावसो

मैं एक वेब सर्वर पर matplotlib चला रहा हूं इसलिए यह मेरे लिए जवाब था। मैंने कोई दुष्प्रभाव नहीं देखा है।
स्पिट्ज

42

स्वच्छ उत्तर में थोड़ा सा समय लेना है ताकि आप अपने निष्पादन के माहौल को सही ढंग से तैयार कर सकें।

पहली तकनीक है कि आप अपने निष्पादन वातावरण तैयार करने के लिए एक प्रयोग है matplotlibrcफ़ाइल, के रूप में बुद्धिमानी से क्रिस प्र द्वारा सिफारिश की , की स्थापना

backend : Agg

उस फ़ाइल में। आप यहां तक ​​कि नियंत्रित कर सकते हैं - कोई कोड परिवर्तन के साथ - कैसे और कहाँ matplotlib matplotlibrcफ़ाइल के लिए दिखता है और ढूँढता है

दूसरी तकनीक जो आपको अपने निष्पादन वातावरण को तैयार करने के लिए है वह है MPLBACKENDपर्यावरण चर का उपयोग करना (और अपने उपयोगकर्ताओं को इसका उपयोग करने के लिए सूचित करना):

export MPLBACKEND="agg"
python <program_using_matplotlib.py>

यह आसान है क्योंकि आपको इस काम को करने के लिए डिस्क पर एक और फ़ाइल भी प्रदान करने की आवश्यकता नहीं है। मैंने इस दृष्टिकोण के साथ नियोजित किया है, उदाहरण के लिए, निरंतर एकीकरण में परीक्षण और दूरस्थ मशीनों पर चल रहा है जिसमें डिस्प्ले नहीं है।

अपने पाइथन कोड में अपने matplotlib बैकेंड को "कोड" में हार्ड-कोडिंग करना एक चौकोर खूंटी को एक बड़े हथौड़े से गोल छेद में सेंकने जैसा है, जब, इसके बजाय, आप सिर्फ matplotlib को बता सकते थे कि इसे एक चौकोर छेद होना चाहिए।


दूसरी तकनीक इस स्थिति में सबसे सुरुचिपूर्ण की तरह दिखती है।
दिमित्री कबानोव

MPLBACKEND का उपयोग करके इसे मेरे लिए हल किया गया। निश्चित रूप से सबसे सुरुचिपूर्ण तरीका!
SaturnFromTitan

41

स्पार्क के माध्यम से matplotlib का उपयोग करते समय मुझे त्रुटि मिली। matplotlib.use('Agg')मेरे लिए काम नहीं करता है। अंत में, निम्न कोड मेरे लिए काम करता है। अधिक यहाँ

import matplotlib.pyplot as plt.
plt.switch_backend('agg')

यह महान काम करता है, matplotlib और अन्य पुस्तकालयों को आयात करने के लिए उपयोग किए जाने वाले आदेश पर प्रतिबंध के बिना।
पाबोररे

स्पार्क पर चलने पर, क्या आपको इसे सिर के नोड पर चलाने के लिए प्रतिबंधित करना होगा या क्या आपको श्रमिक नोड्स पर चलने पर यह काम करना था?
साका

मैं एक django परियोजना में इसका उपयोग कर रहा हूं और यह एकमात्र तरीका है जिससे मैं इसे काम कर सकता हूं।
हेनरी

31

मैं सिर्फ वही दोहराऊंगा जो @Ivo Bosticky ने कहा था जिसे अनदेखा किया जा सकता है। इन लाइनों को py फ़ाइल के VERY प्रारंभ में रखें।

import matplotlib
matplotlib.use('Agg') 

या किसी को त्रुटि मिलेगी

* (usr / lib / pymodules / python2.7 / matplotlib / __ init__.py:923: UserWarning: इस कॉल का matplotlib.use () पर कोई प्रभाव नहीं है
क्योंकि बैकएंड पहले ही चुना जा चुका है;
matplotlib.use () को * pylab, matplotlib.pyplot, * से पहले * कहा जाना चाहिए

यह सभी प्रदर्शन समस्या को हल करेगा


15

मुझे यह स्निपेट एक्स और नो-एक्स वातावरण के बीच स्विच करते समय अच्छी तरह से काम करने के लिए मिला।

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

मेरी राय में, यह स्वीकार किए जाते हैं की तुलना में एक बेहतर समाधान है, हालांकि यह सीधे सवाल का जवाब नहीं देता है, और पूछे गए सवाल का जवाब नहीं देता है।
Daisuke Aramaki

14

कोड को निष्पादित करने के लिए सर्वर में साइन इन करने के बजाय इसका उपयोग करें:

ssh -X username@servername

-Xकोई प्रदर्शन नाम और कोई $ प्रदर्शन वातावरण चर त्रुटि से छुटकारा मिल जाएगा

:)


1
.Png छवि को सहेजने के लिए मुझे '-X' का उपयोग करने की आवश्यकता है। बहुत धन्यवाद।
ओपन स्कूल

यह एक लंबी प्रक्रिया के लिए विफल हो जाएगा यदि ssh बार बाहर, या यदि आपको किसी भी कारण से डिस्कनेक्ट करने की आवश्यकता है। ध्यान दें कि यदि कनेक्टिंग क्लाइंट नींद में चला जाए तो एक टाइमआउट भी हो सकता है।
१६

आप टाइमआउट को जोड़कर रोक सकते हैं -o ServerAliveCountMax=120 -o ServerAliveInterval=30जो ssh क्लाइंट को अधिकतम 1 घंटे के लिए हर 30 सेकंड में एक खाली पैकेट भेज देगा।
एलेक्स

5

आप किस सिस्टम पर हैं? ऐसा लगता है कि आपके पास X11 के साथ एक प्रणाली है, लेकिन DISPLAY वातावरण चर ठीक से सेट नहीं किया गया था। निम्नलिखित कमांड को निष्पादित करने का प्रयास करें और फिर अपने कार्यक्रम को पुन: निर्देशित करें:

export DISPLAY=localhost:0

लेकिन इसे डिस्प्ले वेरिएबल सेट करने के लिए ईड क्यों होता है, मैं दूरस्थ रूप से इस सर्वर पर लॉग इन करता हूं, यह सब करना चाहिए एक पीएनजी फ़ाइल उत्पन्न करता है ???
krisdigitx

1
@krisdigitx, यदि आप दूरस्थ रूप से जुड़े हुए हैं, तो प्रदर्शन चर सेट न करें; जब आप कनेक्ट करते हैं तो "-XY" ध्वज का उपयोग करें। प्रदर्शित करने के लिए, यह जानने की जरूरत है कि छवि को किस Xserver को भेजना है; इस स्थिति में, यह दूरस्थ कंप्यूटर के बजाय आपके कंप्यूटर का प्रदर्शन होगा। "-XY" ध्वज का उपयोग करने से SSH कनेक्ट कंप्यूटर के प्रदर्शन को इंगित करने के लिए प्रदर्शन चर को स्वचालित रूप से सेट करता है।
माइकल आरोन सफ़यान

@krisdigitx, मैं सहमत हूँ, यह बहुत अजीब है कि यह ऐसा करता है; हालांकि, मेरा अनुमान है कि यह X11 का उपयोग करके छवि को पेंट करता है, और फिर X11 का उपयोग करके परिणाम बचाता है।
माइकल आरोन सफ़ियान

$ DISPLAY के लिए इस सेटिंग का उपयोग करना EC2 पर काम नहीं करता है Ubuntu 16 - "लोकलहोस्ट: 0" प्रदर्शित करने के लिए कनेक्ट नहीं कर सका
PabTorre


3

जांच करने के लिए एक और बात यह है कि क्या आपका वर्तमान उपयोगकर्ता एक्स डिस्प्ले से कनेक्ट करने के लिए अधिकृत है। मेरे मामले में, रूट को ऐसा करने की अनुमति नहीं थी और मैटलपोटलिब उसी त्रुटि के साथ शिकायत कर रहा था।

user@debian:~$ xauth list         
debian/unix:10  MIT-MAGIC-COOKIE-1  ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xauth add debian/unix:10  MIT-MAGIC-COOKIE-1 ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xterm

स्रोत: http://www.debian-administration.org/articles/494 https://debian-administration.org/article/494/Getting_X11_forwarding_through_ssh_working_after_running_su


2

यह सुनिश्चित करने के लिए कि आपका कोड विंडोज़, लिनक्स और ओएसएक्स पर पोर्टेबल है और बिना डिस्प्ले वाले सिस्टम के लिए, मैं निम्नलिखित स्निपेट का सुझाव दूंगा:

import matplotlib
import os
# must be before importing matplotlib.pyplot or pylab!
if os.name == 'posix' and "DISPLAY" not in os.environ:
    matplotlib.use('Agg')

# now import other things from matplotlib
import matplotlib.pyplot as plt

साभार: https://stackoverflow.com/a/45756291/207661


1

Google क्लाउड मशीन लर्निंग इंजन के लिए:

import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages

और फिर फाइल करने के लिए प्रिंट करें:

#PDF build and save
    def multi_page(filename, figs=None, dpi=200):
        pp = PdfPages(filename)
        if figs is None:
            figs = [mpl.pyplot.figure(n) for n in mpl.pyplot.get_fignums()]
        for fig in figs:
            fig.savefig(pp, format='pdf', bbox_inches='tight', fig_size=(10, 8))
        pp.close()

और पीडीएफ बनाने के लिए:

multi_page(report_name)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.