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


178

Matplotlib'deki arsa marjlarımla uğraşmak için mücadele ediyorum. Grafiğimi oluşturmak için aşağıdaki kodu kullandım:

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

Bununla birlikte, arsanın her iki tarafında çok fazla beyaz boşluk olan bir çıktı figürü alıyorum. Google'da arama yaptım ve matplotlib dokümanlarını okudum, ancak bunu nasıl azaltacağımı bulamıyorum.


Sorunun boşluk miktarı mı extentait imshowşekil veya tarafından oluşturulan şekil etrafında çıkan png sınır boşluk miktarı, savefig?
unutbu

Her ikisini de düşünüyorum - hem görüntüleme penceresinde hem de PNG'de çok fazla alan var gibi görünüyor. Ancak, önemli çıktı tarafından üretilen png dosyası savefig- bu yüzden sıralamak istiyorum.
robintw

Daha sonra onları GIMP'de kırpıyorum. : /
endolit

Yanıtlar:


251

Bunu otomatik olarak yapmanın bir yolu bbox_inches='tight'kwarg'tır plt.savefig.

Örneğin

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

Başka bir yol kullanmak 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
Bunu varsayılan yapmanın bir yolu var mı?
endolith

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

1
Tüm bunlar, oluşturulduktan sonra görüntüyü kırpmaktır; belirli bir çözünürlüğü uygulamaya çalışıyorsanız, görüntü daha küçük olur .
detly

5
@detly - Evet. Tam olarak yaptığı budur ("dışarı" da kırpıp görüntüyü büyütebilir). İstediğiniz şey için bir göz atın fig.tight_layout(). Bu fonksiyon ilk başta bu cevap yazıldığında mevcut değildi, aksi takdirde daha belirgin olarak bahsederdim.
Joe Kington

2
Birisi bir problemi varsa, kullanınfig = plt.gcf()
KyungHoon Kim

148

Subplots_adjust () işlevini kullanarak matplotlib figürlerinin çevresindeki aralığı ayarlayabilirsiniz:

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

Bu, hem ekrandaki şekil için hem de bir dosyaya kaydedilir ve bir şekil üzerinde birden fazla çiziminiz olmasa bile aramak için doğru işlevdir.

Sayılar şekil boyutlarının parçalarıdır ve şekil etiketlerine izin vermek için ayarlanması gerekir.


8
Parametrelere atanan değerler ve ne kadar değiştirileceğini değil, marjın nereye ayarlanacağını belirtir. Başka bir deyişle, sağ kenar boşluğunu% 10 getirmek istiyorsanız, sağ = 0,9, doğru değil = 0,1 matplotlib.sourceforge.net/api/…
drootang

1
Plt.subplots_adjust () içinde negatif değerler belirtebileceğinizi belirtmek mantıklıdır. Bunu yapmak, figür alanının dışına çizmenize ve sinir bozucu kenar boşluklarıyla başa çıkmanıza izin verir.
surchs

Bu GridSpec, updateyöntemi çağırarak nesneler üzerinde de çalışır (bkz. Stackoverflow.com/a/20058199/1030876 ).
Aaron Voelker

57

Tum ihtiyacin olan sey

plt.tight_layout()

çıkmadan önce.

Kenar boşluklarını azaltmaya ek olarak, bu da herhangi bir alt grafik arasındaki boşluğu sıkı bir şekilde gruplandırır:

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
Bence bu gerçekten en iyi yöntem. Şeklin `` bbox = '' sıkı gibi kaydedilmesini gerektirmez ve sıkışık şekillerdeki diğer tüm düzen sorunlarını düzeltir.
dshepherd

2
bu doğru cevap olmalıdır, çünkü resim yerine ŞEKİL için geçerli olacağından beklediğiniz gibi davranır.
Majid alDosari

Garip bir şekilde, bu aynı zamanda gerçek arsanın genişliğini de değiştirir (yani tepeler birbirine daha yakındır) bbox_inches='tight', bu sadece kenarların etrafındaki beyaz boşluğu kırpır, ancak arsayı yalnız bırakır. Rakamı ile yarattım plt.figure(figsize=(10,3)).
Fritz

9

Sadece ax = fig.add_axes([left, bottom, width, height]) şekil düzeninin tam kontrolünü istiyorsanız kullanın . Örneğin.

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

6

Herhangi biri uyguladıktan sonra beyaz kenar boşluğunun geri kalanından nasıl kurtulacağını merak ederse plt.tight_layout()veya fig.tight_layout(): Parametre ile pad( 1.08varsayılan olarak) daha da sıkılaştırabilirsiniz: "Şekil kenarı ve kenarları arasında dolgu yazı tipi boyutunun bir bölümü olarak. Yani mesela

plt.tight_layout(pad=0.05)

çok küçük bir marja indirir. Koymak 0benim için işe yaramıyor çünkü alt bölümün kutusunun da biraz kesilmesini sağlıyor.


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

1
"pad_inches = -1" çünkü savefig dosyam şeklin yalnızca bir kısmını üretiyor.
Yu Shen

İşlevde bir parametre kullanmak savefigzariftir, ancak pad_inchesher durumda için negatif değere gerek yoktur.
MichaelHuelsen

0 olarak ayarlayın, yardımcı olur
Joop

4

Matplotlibs subplots_adjust ile ilgili problem, girdiğiniz değerlerin şeklin x ve y figürlerine göreli olmasıdır. Bu örnek, bir pdf'in yazdırılması için doğru rakamlandırma içindir:

Bunun için, bu gibi mutlak değerlere göreli aralığı yeniden hesaplar:

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)

x-boyutunda 'figure.xsize' inç rakamı ve y-boyutunda 'figure.ysize' inç rakamı için. Böylece tüm şeklin sol kenar boşluğu 5 mm, alt kenar boşluğu 4 mm, sağ 1 mm ve 3 mm üst kısmı etiketlerin içine yerleştirilir. (X / 25.4) dönüşümü yapılır, çünkü mm'yi inç'e dönüştürmem gerekiyordu.

X'in saf grafik boyutunun inç olarak "figure.xsize - sol kenar boşluğu - sağ kenar boşluğu" ve y'nin saf grafik boyutunun "figure.ysize - alt kenar boşluğu - üst kenar boşluğu" olacağını unutmayın.

Diğer snipletler (bunlardan emin değilim, sadece diğer parametreleri sağlamak istedim)

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

ve

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

3
Nereden xsizeve ysizenereden aldın ? Bu özellikleri kullanıyorum ve alıyorumAttributeError: 'Figure' object has no attribute 'xsize'
cj5

4

yukarıda Sammys cevap ilham:

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)

Figsize, kullandığınız demet fig = pyplot.figure(figsize=...)


2

Benim için, yukarıdaki cevaplar matplotlib.__version__ = 1.4.3Win7'de işe yaramadı . Bu nedenle, yalnızca resmin kendisiyle ilgileniyorsak (yani, ek açıklamalara, eksene, kenelere, başlıklara, ylabellere vb. İhtiyacımız yoksa), numpy dizisini bunun yerine resim olarak kaydetmek daha iyidir 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)

Ayrıca, opencv çizim fonksiyonlarını (cv2.line, cv2.polylines) kullanarak, doğrudan numpy dizisinde bazı çizimler yapabiliriz. http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html


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.