Matplotlib प्लॉट में बाएं और दाएं मार्जिन को कम करें


178

मैं अपने प्लॉट मार्जिन से निपटने के लिए संघर्ष कर रहा हूं। मैंने अपना चार्ट बनाने के लिए नीचे दिए गए कोड का उपयोग किया है:

plt.imshow(g)
c = plt.colorbar()
c.set_label("Number of Slabs")
plt.savefig("OutputToUse.png")

हालांकि, मुझे प्लॉट के दोनों ओर बहुत सारे सफेद स्थान के साथ एक आउटपुट आंकड़ा मिलता है। मैंने Google खोज की है और matplotlib दस्तावेज़ीकरण पढ़ा है, लेकिन मैं यह नहीं जान सकता कि इसे कैसे कम किया जाए।


समस्या में खाली स्थान के की राशि है extentकी imshowआंकड़ा है, या परिणामी png में सीमा से व्हाइटस्पेस की राशि, आंकड़ा आसपास, द्वारा उत्पन्न savefig?
unutbu

मुझे लगता है कि दोनों - देखने की खिड़की और पीएनजी में बहुत जगह है। हालाँकि, महत्वपूर्ण आउटपुट png फ़ाइल द्वारा निर्मित है savefig- तो यही वह है जो मैं सॉर्ट करना चाहूंगा।
रोबिन्ट

मैं बस उन्हें GIMP में बाद में क्रॉप कर रहा हूं। : /
एंडोलिथ

जवाबों:


251

एक तरह से स्वचालित रूप से ऐसा करने के लिए है bbox_inches='tight'करने के लिए kwarg plt.savefig

उदाहरण के लिए

import matplotlib.pyplot as plt
import numpy as np
data = np.arange(3000).reshape((100,30))
plt.imshow(data)
plt.savefig('test.png', bbox_inches='tight')

दूसरा तरीका उपयोग करना है fig.tight_layout()

import matplotlib.pyplot as plt
import numpy as np

xs = np.linspace(0, 1, 20); ys = np.sin(xs)

fig = plt.figure()
axes = fig.add_subplot(1,1,1)
axes.plot(xs, ys)

# This should be called after all axes have been added
fig.tight_layout()
fig.savefig('test.png')

5
क्या इसे डिफ़ॉल्ट बनाने का कोई तरीका है?
एंडोलिथ

1
यदि आपके पास कई सबप्लॉट हैं और उनमें से प्रत्येक को बचाना चाहते हैं, तो आप इसके साथ fig.savefig()भी उपयोग कर सकते हैं । ( plt.savefig()उस मामले में काम नहीं करेगा।)
अभिनील दास

1
यह सब फसल के बाद यह छवि है; यदि आप किसी विशेष रिज़ॉल्यूशन को लागू करने की कोशिश कर रहे हैं, तो छवि छोटी हो जाएगी
detly

5
@detly - हां। यह वास्तव में यही करता है (हालांकि यह "आउट" भी कर सकता है और छवि को बड़ा कर सकता है, साथ ही साथ)। आप जो चाहते हैं, उसके लिए एक नजर है fig.tight_layout()। जब यह उत्तर मूल रूप से लिखा गया था, तब यह फ़ंक्शन मौजूद नहीं था, अन्यथा मैं इसका अधिक प्रमुखता से उल्लेख करता।
जो किंग्सटन

2
अगर किसी को कोई समस्या है, तो उपयोग करेंfig = plt.gcf()
KyungHoon Kim

148

आप subplots_adjust () फ़ंक्शन का उपयोग करके matplotlib आंकड़ों के आसपास रिक्ति को समायोजित कर सकते हैं:

import matplotlib.pyplot as plt
plt.plot(whatever)
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)

यह स्क्रीन पर दोनों आकृति के लिए काम करेगा और एक फ़ाइल में सहेजा जाएगा, और यह कॉल करने का सही कार्य है, भले ही आपके पास एक आंकड़े पर कई प्लॉट न हों।

संख्या आंकड़ा आयामों के अंश हैं, और आंकड़ा लेबल के लिए अनुमति देने के लिए समायोजित करने की आवश्यकता होगी।


8
मान पैरामीटर को निर्दिष्ट किए गए हैं और न कि इसे कितना बदलना है, वे मार्जिन सेट करने के लिए कहां हैं। दूसरे शब्दों में, यदि आप 10% द्वारा सही बढ़त मार्जिन लाना चाहते हैं, तो आपको सही = 0.9 सेट करना चाहिए, सही नहीं = 0.1 matplotlib.sourceforge.net/api/…
drootang

1
यह इंगित करने के लिए समझ में आता है कि स्पष्ट रूप से आप plt.subplots_adjust () में नकारात्मक मान निर्दिष्ट कर सकते हैं। ऐसा करने से आप फिगर क्षेत्र से बाहर निकल सकते हैं और कष्टप्रद मार्जिन से भी निपट सकते हैं।
15

यह विधि GridSpecको कॉल करके ऑब्जेक्ट पर भी काम करता है update(देखें stackoverflow.com/a/20058199/1030876 )।
आरोन वोल्कर

57

जो तुम्हे चाहिए वो है

plt.tight_layout()

अपने आउटपुट से पहले।

हाशिये को काटने के अलावा, यह किसी भी सबप्लॉट के बीच की जगह को भी कस कर रखता है:

x = [1,2,3]
y = [1,4,9]
import matplotlib.pyplot as plt
fig = plt.figure()
subplot1 = fig.add_subplot(121)
subplot1.plot(x,y)
subplot2 = fig.add_subplot(122)
subplot2.plot(y,x)
fig.tight_layout()
plt.show()

7
मुझे लगता है कि यह वास्तव में सबसे अच्छी विधि है। यह `bbox = 'तंग' जैसी आकृति को सहेजने की आवश्यकता नहीं है और तंग आकृतियों में अन्य सभी प्रकार की लेआउट समस्याओं को हल करता है।
dshepherd

2
यह सही उत्तर होना चाहिए क्योंकि यह वैसा ही व्यवहार करता है जैसा आप अपेक्षा करते हैं क्योंकि यह छवि के बजाय FIGURE पर लागू होता है।
माजिद अलदोसारी

अजीब तरह से, यह वास्तविक भूखंड की चौड़ाई को भी बदलता है (यानी चोटियां एक साथ करीब हैं) bbox_inches='tight', जो कि किनारों के चारों ओर सफेद स्थान को क्लिप करता है, लेकिन अकेले भूखंड को छोड़ देता है। मैंने इसके साथ आकृति बनाई plt.figure(figsize=(10,3))
फ्रिट्ज़

9

ax = fig.add_axes([left, bottom, width, height]) यदि आप आंकड़ा लेआउट का सटीक नियंत्रण चाहते हैं तो बस उपयोग करें । जैसे।

left = 0.05
bottom = 0.05
width = 0.9
height = 0.9
ax = fig.add_axes([left, bottom, width, height])

6

मामले में कोई भी आश्चर्य करता है कि आवेदन करने के बाद सफेद मार्जिन के बाकी हिस्सों से कैसे छुटकारा पाएं plt.tight_layout()या fig.tight_layout(): पैरामीटर pad(जो 1.08डिफ़ॉल्ट रूप से है) के साथ, आप इसे और भी तंग करने में सक्षम हैं: "आंकड़ा किनारे और किनारों के बीच पैडिंग फ़ॉन्ट आकार के एक अंश के रूप में उपपट्टियाँ, " इसलिए उदाहरण के लिए

plt.tight_layout(pad=0.05)

इसे बहुत कम मार्जिन से कम करेगा। पुटिंग 0मेरे लिए कारगर नहीं है, क्योंकि यह सबप्लॉट के बॉक्स को थोड़ा-बहुत काट देता है।


4
plt.savefig("circle.png", bbox_inches='tight',pad_inches=-1)

1
"pad_inches = -1" मेरे savefig का कारण केवल आकृति का हिस्सा है।
यू शेन

savefigफ़ंक्शन में एक पैरामीटर का उपयोग करना सुरुचिपूर्ण है, हालांकि pad_inchesहर मामले में नकारात्मक मूल्य की आवश्यकता नहीं है।
माइकलहुलेसन

इसे 0 पर सेट करें, मदद करता है
जोप

4

Matplotlibs subplots_adjust के साथ समस्या यह है कि आपके द्वारा दर्ज किए गए मान x और y के आंकड़े के सापेक्ष हैं। यह उदाहरण एक पीडीएफ की छपाई के लिए सही आंकड़े देने के लिए है:

उसके लिए, मैं इस तरह के पूर्ण मूल्यों के सापेक्ष रिक्ति की गणना करता हूं:

pyplot.subplots_adjust(left = (5/25.4)/figure.xsize, bottom = (4/25.4)/figure.ysize, right = 1 - (1/25.4)/figure.xsize, top = 1 - (3/25.4)/figure.ysize)

एक्स-डायमेंशन में 'फिगर.एक्ससाइज' इंच की आकृति के लिए और वाई-डायमेंशन में 'फिगर.साइज' इंच के लिए। तो पूरे आंकड़े में 5 मिमी का बायाँ मार्जिन, 4 मिमी का निचला भाग, 1 मिमी का दाईं ओर और लेबल के भीतर 3 मिमी का शीर्ष रखा गया है। (X / 25.4) का रूपांतरण इसलिए किया जाता है क्योंकि मुझे मिमी को इंच में बदलने की आवश्यकता थी।

ध्यान दें कि x का शुद्ध चार्ट आकार "फिगर.एक्ससाइज़ - लेफ्ट मार्जिन - राइट मार्जिन" होगा और वाई का प्योर चार्ट साइज़ इंच में "फिगर.साइज़ - बॉटम मार्जिन - टॉप मार्जिन" होगा।

अन्य स्नाइपर्स (इन लोगों के बारे में निश्चित नहीं हैं, मैं सिर्फ अन्य मापदंडों को प्रदान करना चाहता था)

pyplot.figure(figsize = figureSize, dpi = None)

तथा

pyplot.savefig("outputname.eps", dpi = 100)

3
आपको कहां से xsizeऔर कहां मिला ysize। मैं उन गुणों का उपयोग करता हूं और मुझे मिलता हैAttributeError: 'Figure' object has no attribute 'xsize'
cj5

4

ऊपर Sammys जवाब से प्रेरित:

margins = {  #     vvv margin in inches
    "left"   :     1.5 / figsize[0],
    "bottom" :     0.8 / figsize[1],
    "right"  : 1 - 0.3 / figsize[0],
    "top"    : 1 - 1   / figsize[1]
}
fig.subplots_adjust(**margins)

जहाँ अंजीर का उपयोग किया जाता है, वह है fig = pyplot.figure(figsize=...)


2

मेरे लिए, उपरोक्त उत्तर matplotlib.__version__ = 1.4.3Win7 पर काम नहीं करते थे । इसलिए, यदि हम केवल छवि में ही रुचि रखते हैं (यानी, अगर हमें एनोटेशन, अक्ष, टिक, शीर्षक, यलैबेल आदि की आवश्यकता नहीं है), तो बेहतर है कि आप केवल छवि के रूप में खस्ता सरणी को बचाएं savefig

from pylab import *

ax = subplot(111)
ax.imshow(some_image_numpyarray)
imsave('test.tif', some_image_numpyarray)

# or, if the image came from tiff or png etc
RGBbuffer = ax.get_images()[0].get_array()
imsave('test.tif', RGBbuffer)

इसके अलावा, opencv ड्रॉइंग फ़ंक्शंस (cv2.line, cv2.polylines) का उपयोग करके, हम सीधे आकृतियों पर कुछ चित्र बना सकते हैं। http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html


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