Matplotlib में एक सहेजी गई छवि के आसपास सफेद स्थान को हटाना


172

मुझे कुछ प्रक्रिया के बाद एक छवि लेने और इसे बचाने की आवश्यकता है। जब मैं इसे प्रदर्शित करता हूं तो आंकड़ा ठीक दिखता है, लेकिन आकृति को सहेजने के बाद, मुझे सहेजी गई छवि के आसपास कुछ सफेद स्थान मिला। मैंने विधि के 'tight'लिए विकल्प की कोशिश की है savefig, या तो काम नहीं किया। कोड:

  import matplotlib.image as mpimg
  import matplotlib.pyplot as plt

  fig = plt.figure(1)
  img = mpimg.imread(path)
  plt.imshow(img)
  ax=fig.add_subplot(1,1,1)

  extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
  plt.savefig('1.png', bbox_inches=extent)

  plt.axis('off') 
  plt.show()

मैं एक आकृति पर NetworkX का उपयोग करके और इसे बचाने के लिए एक मूल ग्राफ खींचने की कोशिश कर रहा हूं। मैंने महसूस किया कि ग्राफ के बिना यह काम करता है, लेकिन जब एक ग्राफ जोड़ा जाता है तो मुझे सहेजी गई छवि के आसपास सफेद स्थान मिलता है;

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

G = nx.Graph()
G.add_node(1)
G.add_node(2)
G.add_node(3)
G.add_edge(1,3)
G.add_edge(1,2)
pos = {1:[100,120], 2:[200,300], 3:[50,75]}

fig = plt.figure(1)
img = mpimg.imread("C:\\images\\1.jpg")
plt.imshow(img)
ax=fig.add_subplot(1,1,1)

nx.draw(G, pos=pos)

extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig('1.png', bbox_inches = extent)

plt.axis('off') 
plt.show()


मेरे लिए वास्तव में जो काम किया गया था वह एक और टूल का उपयोग करके पीडीएफ को क्रॉप करना था, जैसे कि पीडीएफक्रॉप।
टोलिविरा

जवाबों:


170

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

plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
            hspace = 0, wspace = 0)
plt.margins(0,0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.savefig("filename.pdf", bbox_inches = 'tight',
    pad_inches = 0)

मैंने इसके विभिन्न हिस्सों को निष्क्रिय करने की कोशिश की है, लेकिन यह हमेशा कहीं न कहीं एक सफेद मार्जिन की ओर ले जाता है। आपने मार्जिन की कमी के कारण फिगर लाइनों को शेव होने से दूर रखने के लिए इसे संशोधित भी किया होगा।


6
अंत में कुछ है कि काम करता है, बहुत बहुत धन्यवाद! वैसे, मेरे मामले में केवल दो लाइनों का उपयोग set_major_locatorकरना आवश्यक था।
फ्लोरियन ब्रूकर

6
मैंने आखिरी घंटे विभिन्न चीजों की कोशिश में बिताए हैं और 1px सफेद सीमा से छुटकारा नहीं पा सका। यह केवल एक चीज थी जो काम करती थी - विशेष रूप से pad_inches=0जो अन्य उत्तरों का उल्लेख नहीं करती है।
अन्नमय

1
set_major_locatorमेरे लिए महत्वपूर्ण था।
किमीैक

16
pad_inchesमेरी मदद की।
माइल बेकर

5
matplotlib.ticker.NullLocator ()
जोप

200

आप की स्थापना करके सफेद स्थान गद्दी से हटा सकते हैं bbox_inches="tight"में savefig:

plt.savefig("test.png",bbox_inches='tight')

आपको तर्क को bbox_inchesएक स्ट्रिंग के रूप में रखना होगा , शायद यही कारण है कि यह आपके लिए पहले काम नहीं करता था।


संभव डुप्लिकेट:

माटप्लोटलिब प्लॉट्स: धुरी, किंवदंतियों और सफेद स्थानों को हटाना

कैसे एक matplotlib आंकड़ा के लिए मार्जिन सेट करने के लिए?

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


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

30
यह बिलकुल सही नहीं है । जब आप उस bbox_inchesविकल्प का उपयोग करते हैं , तो एक और डिफ़ॉल्ट होता है जो कुछ स्थान छोड़ता है। यदि आप वास्तव में सब कुछ से छुटकारा चाहते हैं, तो आपको भी उपयोग करने की आवश्यकता है pad_inches=0.0। बेशक, इस तरह के तंग गद्दी अक्सर काट देता है, जैसे, एक्स्पोनेंट्स ...
माइक

5
साथ ही काले किनारे हटाने के लिए, आप सेट करना पड़ सकता हैpad_inches=-0.1
lenhhoxung

10
यह बस काम नहीं करता है, आप अभी भी आंकड़ा के आसपास व्हाट्सएप प्राप्त करते हैं। पारदर्शी विकल्प सेट करना (जैसा कि कुछ उत्तरों में उल्लेख किया गया है) वास्तव में या तो मदद नहीं करता है, व्हाट्सएप अभी भी है, यह केवल पारदर्शी है।
ब्योर्नॉव

1
@piperchester यह एक अच्छा सवाल है, लेकिन शायद एक नए सवाल के रूप में पूछा जाना चाहिए ताकि यह टिप्पणियों में खो न जाए। आपको नए प्रश्न को पुराने से जोड़ना चाहिए, हालाँकि!
हुक

21

बिना किसी सफलता (और अन्य स्टैक पोस्ट्स के एक धसान) के साथ उपरोक्त उत्तरों की कोशिश करने के बाद आखिरकार मेरे लिए क्या काम किया गया

plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
            hspace = 0, wspace = 0)
plt.margins(0,0)
plt.savefig("myfig.pdf")

महत्वपूर्ण रूप से इसमें बॉक्स या पेडिंग तर्क शामिल नहीं हैं।


4
यह स्वीकृत उत्तर होना चाहिए। इसके अतिरिक्त, आपको कॉल करने की भी आवश्यकता नहीं है set_axis_off। यह सहेजे गए छवि को प्रभावित नहीं करता है क्योंकि subplots_adjustअक्ष आंकड़ा के बाहर झूठ होने के बाद और हेनवे वैसे भी नहीं होगा। हालाँकि, जुपाइटर नोटबुक में, आपको अक्ष को स्पष्ट रूप से अक्षम करने की आवश्यकता होती है, क्योंकि इनलाइन बैकएंड इन सेटिंग्स को ओवरराइट कर देता है।
मैक्सपॉवर

20

मुझे अरविंद परेरा ( http://robotics.usc.edu/~ampereir/wordpress/?p=626 ) से कुछ मिला और मेरे लिए काम करने लगा:

plt.savefig(filename, transparent = True, bbox_inches = 'tight', pad_inches = 0)

7
transparent=Trueऐसा लगेगा कि कोई समस्या नहीं है, लेकिन यह सिर्फ सफेद स्थान छिपाएगा, छवि आयाम ठीक नहीं होंगे।
व्लादि वेसलिनोव

उल्लेख करने के लिए धन्यवाद pad_inches! काश मुझे इस विकल्प के बारे में पहले पता होता!
ingomueller.net

1
यह अधिकांश भूखंडों के लिए काम करता है, लेकिन इसने मेरे भ्रम मैट्रिक्स के लिए सही सीमा को हटा दिया। बस एक छोटे से पैडिंग जोड़ेंpad_inches=.25
YTZ

14

निम्नलिखित समारोह में जोहान्स-एस का उत्तर शामिल है। मैंने इसे कई अक्षों के साथ plt.figureऔर इसके साथ परीक्षण किया है plt.subplots(), और यह अच्छी तरह से काम करता है।

def save(filepath, fig=None):
    '''Save the current image with no whitespace
    Example filepath: "myfig.png" or r"C:\myfig.pdf" 
    '''
    import matplotlib.pyplot as plt
    if not fig:
        fig = plt.gcf()

    plt.subplots_adjust(0,0,1,1,0,0)
    for ax in fig.axes:
        ax.axis('off')
        ax.margins(0,0)
        ax.xaxis.set_major_locator(plt.NullLocator())
        ax.yaxis.set_major_locator(plt.NullLocator())
    fig.savefig(filepath, pad_inches = 0, bbox_inches='tight')

एक जादू की तरह काम किया। पिछले जवाब में मेरे निर्यात में कुछ आवश्यक आदेश थे।
केविन एस

11

मैंने पाया कि निम्नलिखित कोड काम के लिए पूरी तरह से काम करते हैं।

fig = plt.figure(figsize=[6,6])
ax = fig.add_subplot(111)
ax.imshow(data)
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
ax.set_frame_on(False)
plt.savefig('data.png', dpi=400, bbox_inches='tight',pad_inches=0)

2
आम तौर पर, उत्तर बहुत अधिक सहायक होते हैं यदि वे इस बात का स्पष्टीकरण शामिल करते हैं कि कोड क्या करने का इरादा है, और क्यों यह दूसरों को पेश किए बिना समस्या को हल करता है।
टिम डाइकमैन

7

मैंने इस क्रम का पालन किया और इसने एक आकर्षण की तरह काम किया।

plt.axis("off")
fig=plt.imshow(image array,interpolation='nearest')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('destination_path.pdf',
    bbox_inches='tight', pad_inches=0, format='pdf', dpi=1200)

1
वास्तव में, मैंने पाया कि यह उत्तर प्रयोग करने में आसान और अधिक सुविधाजनक है।
सिक्सिस

1
यह एक मेरे लिए काम किया; स्वीकृत उत्तर नहीं दिया गया।
जो

3

जो कोई इंच के बजाय पिक्सेल में काम करना चाहता है, उसके लिए यह काम करेगा।

साथ ही सामान्य भी आप की आवश्यकता होगी

from matplotlib.transforms import Bbox

तो आप निम्नलिखित का उपयोग कर सकते हैं:

my_dpi = 100 # Good default - doesn't really matter

# Size of output in pixels
h = 224
w = 224

fig, ax = plt.subplots(1, figsize=(w/my_dpi, h/my_dpi), dpi=my_dpi)

ax.set_position([0, 0, 1, 1]) # Critical!

# Do some stuff
ax.imshow(img)
ax.imshow(heatmap) # 4-channel RGBA
ax.plot([50, 100, 150], [50, 100, 150], color="red")

ax.axis("off")

fig.savefig("saved_img.png",
            bbox_inches=Bbox([[0, 0], [w/my_dpi, h/my_dpi]]),
            dpi=my_dpi)

यहां छवि विवरण दर्ज करें


आपको डीपीआई निर्दिष्ट करने की आवश्यकता नहीं है, आप fig.dpiइसके बजाय डिफ़ॉल्ट एक का उपयोग कर सकते हैं
intsco

1

एक बहुत आसान तरीका जो मुझे मिला वह है उपयोग करने के लिए plt.imsave:

    import matplotlib.pyplot as plt
    arr = plt.imread(path)
    plt.imsave('test.png', arr)

अधूरा जवाब। संकल्प को बनाए रखने और व्हाट्सएप को हटाने के लिए एक लंबी खोज के बाद इसने मेरी मदद की plt.savefig()
nihal111

यह केवल उसी स्थिति में काम करता है जब आप छवि के रूप में एक सरणी (!) को सहेजना चाहते हैं। यह एक मनमाना आंकड़ा बचाने की अनुमति नहीं देता है।
मैक्सपावर

मनमानी छवि से आपका क्या अभिप्राय है? क्या एक छवि मूल्यों की एक सरणी नहीं है?
पार्थ92

0

आप यह कोशिश कर सकते हैं। इसने मेरी समस्या हल कर दी।

import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img, cmap=cmap)

-1

यदि आप यह प्रदर्शित करना चाहते हैं कि क्या सहेजा जाना है तो मैं plt.tight_layoutरूपांतरण का उपयोग करने की सलाह देता हूं जो वास्तव में अधिक बेहतर है क्योंकि यह उपयोग करते समय अनावश्यक क्रॉपिंग नहीं करता हैplt.savefig

import matplotlib as plt    
plt.plot([1,2,3], [1,2,3])
plt.tight_layout(pad=0)
plt.savefig('plot.png')

-4

यह मेरे लिए फ़ाइल के लिए imshow के साथ प्लॉट किए गए एक संख्यात्मक सरणी को सहेजने का काम करता है

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,10))
plt.imshow(img) # your image here
plt.axis("off")
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
        hspace = 0, wspace = 0)
plt.savefig("example2.png", box_inches='tight', dpi=100)
plt.show()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.