Matplotlib'de kaydedilmiş bir görüntünün çevresindeki boşluğu kaldırma


172

Bir görüntü alıp bir süreçten sonra kaydetmem gerekiyor. Gösterdiğimde şekil iyi görünüyor, ancak figürü kaydettikten sonra, kaydedilen görüntünün etrafında biraz beyaz boşluk var. Ben yöntem 'tight'seçeneği denedim, savefigya da işe yaramadı. Kod:

  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()

Bir şekil üzerinde NetworkX kullanarak temel bir grafik çizmek ve kaydetmek çalışıyorum. Grafik olmadan çalıştığını fark ettim, ancak bir grafik eklendiğinde kaydedilen görüntünün etrafında beyaz boşluk elde ederim;

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()


Benim için gerçekten işe yarayan, pdf'i pdfcrop gibi başka bir araç kullanarak kırpmaktı.
toliveira

Yanıtlar:


170

“Çözümüm” ün neden ya da nasıl çalıştığını tam olarak bildiğimi iddia edemiyorum, ancak beyaz kenar boşlukları olmayan bir çift kanat profili bölümünün taslağını bir PDF dosyasına çizmek istediğimde bunu yapmam gerekiyordu. (-Pylab bayrağıyla bir IPython not defterinde matplotlib kullandığımı unutmayın.)

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)

Bunun farklı kısımlarını devre dışı bırakmaya çalıştım, ama bu her zaman beyaz bir kenar boşluğuna yol açıyor. Yağ sınırlarının, sınırların yakınındaki marjların kenar boşluğundan dolayı traş olmasını önlemek için bunu bile değiştirebilirsiniz.


6
Sonunda işe yarayan bir şey, çok teşekkür ederim! Bu arada, benim durumumda sadece iki satır kullanmak set_major_locatorgerekiyordu.
Florian Brucker

6
Geçen saati çeşitli şeyleri denedim ve 1 piksel beyaz bir sınırdan kurtulamadım. Bu işe yarayan tek şeydi - özellikle pad_inches=0diğer cevapların bahsetmediği.
AnnanFay

1
set_major_locatorbenim için önemliydi.
kmac

16
pad_inchesbana yardımcı oldu.
Myles Baker

5
matplotlib.ticker.NullLocator ()
Joop

200

Sen ayarlayarak beyaz boşluk dolgu kaldırabilir bbox_inches="tight"içinde savefig:

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

Argümanı bbox_inchesbir dize olarak koymanız gerekecek , belki de bu yüzden sizin için daha önce işe yaramadı.


Olası kopyalar:

Matplotlib grafikleri: eksen, efsaneler ve beyaz boşlukların kaldırılması

Bir matplotlib figürü için kenar boşlukları nasıl ayarlanır?

Matplotlib grafiğinde sol ve sağ kenar boşluklarını azaltma


1
Birden fazla alt grafiğiniz varsa ve bunların her birini kaydetmek istiyorsanız, bunu da kullanabilirsiniz fig.savefig(). ( plt.savefig()bu durumda çalışmaz.)
Abhranil Das

30
Bu pek doğru değil. Bu bbox_inchesseçeneği kullandığınızda, yer bırakan başka bir varsayılan var. Gerçekten her şeyden kurtulmak istiyorsanız, kullanmanız gerekir pad_inches=0.0. Tabii ki, bu tür sıkı dolgu sık sık keser, örneğin, üsleri ...
Mike

5
Siyah kenarı da çıkarmak için ayarlamanız gerekebilirpad_inches=-0.1
lenhhoxung

10
Bu işe yaramaz, yine de figürün etrafında boşluk kalır. Şeffaf seçeneği ayarlamak (bazı cevaplarda belirtildiği gibi) gerçekten de yardımcı olmaz, boşluk hala oradadır, sadece şeffaftır.
BjornW

1
@piperchester bu iyi bir soru, ama muhtemelen yeni bir soru olarak sorulmalıdır, bu yüzden yorumlarda kaybolmaz. Yine de yeni soruyu eskisine bağlamalısınız!
Hooked

21

Yukarıdaki cevapları hiçbir başarı ile denedikten sonra (ve diğer yığın mesajların) sonunda benim için işe yarayan sadece

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")

Önemli olarak bu, bbox veya dolgu argümanlarını içermez.


4
Bu kabul edilen cevap olmalı. Ayrıca, aramanıza bile gerek yoktur set_axis_off. subplots_adjustEksen şeklin kapsamı dışında kaldıktan ve henve yine de çizilmeyeceği için kaydedilen görüntüyü etkilemez . Bununla birlikte, Jupyter not defterlerinde, satır içi arka uç bu ayarların üzerine yazdığından ekseni açıkça devre dışı bırakmanız gerekir.
MaxPowers

20

Arvind Pereira'dan bir şey buldum ( http://robotics.usc.edu/~ampereir/wordpress/?p=626 ) ve benim için çalışıyor gibiydi:

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

7
transparent=Truesorun yok gibi görünmesini sağlayacak, ancak sadece beyaz alanı gizleyecek, görüntü boyutları iyi olmayacak.
Vlady Veselinov

Bahsettiğiniz için teşekkürler pad_inches! Keşke bu seçeneği daha önce bilseydim!
ingomueller.net

1
Bu, çoğu parsel için işe yarıyor, ancak bu, karışıklık matrisim için doğru sınırı kaldırdı. Sadece küçük bir dolgu ekleyinpad_inches=.25
YTZ

14

Aşağıdaki fonksiyon yukarıda johannes-s cevabını içermektedir. Birden fazla eksenle ve birden fazla eksenle test ettim plt.figureve plt.subplots()güzel çalışıyor.

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')

Bir cazibe gibi çalıştı. Önceki yanıt, dışa aktarımda bazı gerekli komutlardı.
Kevin S

11

Aşağıdaki kodların iş için mükemmel çalıştığını gördüm.

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
Genellikle, kodun ne yapmak istediği ve başkalarını tanıtmadan sorunu neden çözdüğüne dair bir açıklama içeriyorsa, cevaplar çok daha yararlıdır.
Tim Diekmann

7

Ben bu diziyi takip ve bir cazibe gibi çalıştı.

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
Aslında, bu cevabın kolay ve daha kullanışlı olduğunu buldum.
sikisis

1
Bu benim için çalıştı; kabul edilen cevap vermedi.
Joe

3

İnç yerine piksel olarak çalışmak isteyen herkes için bu işe yarayacaktır.

Ayrıca her zamanki gibi

from matplotlib.transforms import Bbox

Ardından aşağıdakileri kullanabilirsiniz:

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)

resim açıklamasını buraya girin


Dpi belirtmeniz gerekmez, fig.dpibunun yerine varsayılan olanı kullanabilirsiniz
intsco

1

Bulduğum çok daha basit bir yaklaşım plt.imsave:

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

Yetersiz cevap. Bu, çözünürlüğü nasıl koruyacağımı ve boşluğu nasıl kaldıracağımı uzun bir aramanın ardından bana yardımcı oldu plt.savefig().
nihal111

Bu yalnızca bir diziyi (!) Resim olarak kaydetmek istediğinizde işe yarar. Bu, keyfi bir rakamın kaydedilmesine izin vermez.
MaxPowers

Rasgele görüntü ile ne demek istiyorsun? Görüntü bir değerler dizisi değil mi?
Parth92

0

Bunu deneyebilirsiniz. Sorunumu çözdü.

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

-1

Kaydedilecekleri görüntülemek istiyorsanız, kullanırken plt.tight_layoutgereksiz kırpma yapmadığı için daha çok tercih edilen bir dönüşüm kullanmanızı öneririz.plt.savefig

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

-4

Bu benim için imshow ile çizilen numpy dizi dosya kaydetmek için çalışır

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()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.