scipy: çerçeveler, eksenler, yalnızca içerik olmadan kaydetme


92

Numpy / scipy'de bir dizide depolanan bir imajım var. Görüntüleyebiliyorum, herhangi bir sınır, eksen, etiket, başlık savefig olmadan kullanarak kaydetmek istiyorum ... Sadece saf görüntü, başka hiçbir şey yok.

PyPNGVeya gibi paketlerden kaçınmak istiyorum scipy.misc.imsave, bazen sorunlu oluyorlar (her zaman iyi yüklenmiyorlar, sadece savefig()benim için temel

Yanıtlar:


115

DÜZENLE

Değişti aspect='normaliçin aspect='auto'o matplotlib daha yeni sürümleri (Luke19 @ sayesinde) değişti beri.


Varsayalım:

import matplotlib.pyplot as plt

Çerçeve olmadan bir figür yapmak için:

fig = plt.figure(frameon=False)
fig.set_size_inches(w,h)

İçeriğin tüm şekli doldurmasını sağlamak için

ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)

Ardından resminizi üzerine çizin:

ax.imshow(your_image, aspect='auto')
fig.savefig(fname, dpi)

aspectParametre emin onlar belirtilen rakam boyutunu dolduracak hale getirmek için piksel boyutunu değiştirir fig.set_size_inches(…). Bu tür şeylerle nasıl oynanacağına dair bir fikir edinmek için, matplotlib'in özellikle Axes, Axis ve Artist konusundaki belgelerini okuyun .


4
hayır, hala küçük şeffaf bir kenarlığım var ve istediğim hiç kenarlık olmaması , saf görüntü
Jakub M.

5
El ayarlanırsa wve hparametreleri fig.set_size_inches(w,h)ve dpiparametre fig.savefig(fname, dpi)yüzden 24px tarafından 24px sonuçlandığını, sadece para cezası çalışmalıdır. Örneğin, w = h = 1vedpi = 24
matehat

5
Hem bu yanıtı hem de aşağıdaki Mostafa Pakparvar yanıtını birleştirmek zorunda kaldım. Yalnızca eksenleri kapatmakla kalmaz, aynı zamanda beyaz boşluğun kaybolduğundan emin olmak için set_visible'ı false olarak ayarlamanız gerekir. (wtf?)
Bryce Guinta

6
Bunu matplotlib v2.2.2 kullanarak denedim ve mükemmel çalıştı ( bunun imshowsözdiziminin aspect='auto'yerine olarak değiştirilmesi dışında 'normal').
Luke19

2
Bu doğru yaklaşımdır. ax = plt.Axes(fig, [0., 0., 1., 1.])çalışmasını sağlayan şeydir.
greatvovan

73

Daha kolay bir çözüm şöyle görünüyor:

fig.savefig('out.png', bbox_inches='tight', pad_inches=0)

2
Bu benim için harika oldu. Ayrıca pad_inches istenilen boyuta kolaylıkla değiştirilebilir. Teşekkürler!
Curious2learn

27
Bununla hala beyaz kenar boşluklarım var.
Fábio Perez

3
Bunu daha yeni sürümler için güncelleyebildim / kalan marj sorununu yalnızca transparent = Truefig.savefig('out.png', bbox_inches='tight',transparent=True, pad_inches=0)
mdoc-2011

2
Hala eksenler, onay işaretleri ve bununla ilgili her şey var :(
BjornW

3
Bu hiç bir şey yapmaz. Size tüm eksenleri ve etiketleri olan şekli verecektir.
1313e

27

Görüntünün bbox'ını eksen içinde bulabilir (kullanarak get_window_extent) ve bu bbox_inchesparametreyi görüntünün yalnızca o kısmını kaydetmek için kullanabilirsiniz :

import numpy as np
import matplotlib.pyplot as plt

data=np.arange(9).reshape((3,3))
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
plt.axis('off')
plt.imshow(data)

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

Bu numarayı burada Joe Kington'dan öğrendim .


6
sadece plt.axis('off')yardım etti. Diğer cevaplar pek yardımcı olmuyor.
imsrgadich

3
Bu oldukça iyi çalıştı. Ancak benim durumumda hala küçük bir beyaz sınır var. Bu sınırı nasıl kaldıracağınıza dair bir fikriniz var mı?
user3731622

@ user3731622, lütfen plt.savefig('/temp/test.png', bbox_inches='tight', transparent=True, pad_inches=0)bunun yerine deneyinplt.savefig('/tmp/test.png', bbox_inches=extent)
Cloud Cho

17

Benim durumumda birkaç seçenek denedim ve en iyi çözüm şuydu:

fig.subplots_adjust(bottom = 0)
fig.subplots_adjust(top = 1)
fig.subplots_adjust(right = 1)
fig.subplots_adjust(left = 0)

sonra figürünüzü kaydedin savefig


1
Tüm bu çözümlerden benim için işe yarayan tek çözüm bu.
Puff

8

Bbox'ı sıkı moda ayarladıktan sonra kalan dolguyu kaldırmak için buradan ödünç alınan küçük bir ek ile heron13 yanıtını önereceğim , bu nedenle:

axes = fig.axes()
axes.get_xaxis().set_visible(False)
axes.get_yaxis().set_visible(False)
fig.savefig('out.png', bbox_inches='tight', pad_inches=0)

Get_xaxis () ve get_yaxis () olmadığını söyleyen bir hata alıyorum. Bunun neden olacağı hakkında bir fikriniz var mı?
Jacob Malachowski

Bir axes () nesnesi yapın, ardından ax.xaxis ve ax.yaxis kullanın
perigon

"Liste" nesnesinin "get_xaxis" özniteliği olmadığını söyleyen bir hata oluştu
Haozhe Xie

7

Bu benim için çalışıyor

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

3

Başka bir bilgi olmadan arsa içeriğini çıkarmak istediğimde librosa kullanarak bazı görselleştirme yaparken aynı sorunu yaşadım . Yani bu benim yaklaşımım. unutbu cevabı da işe koymama yardımcı oluyor.

    figure = plt.figure(figsize=(500, 600), dpi=1)
    axis = plt.subplot(1, 1, 1)
    plt.axis('off')
    plt.tick_params(axis='both', left='off', top='off', right='off', bottom='off', labelleft='off', labeltop='off',
                    labelright='off', labelbottom='off')

     # your code goes here. e.g: I used librosa function to draw a image
    result = np.array(clip.feature_list['fft'].get_logamplitude()[0:2])
    librosa.display.specshow(result, sr=api.Clip.RATE, x_axis='time', y_axis='mel', cmap='RdBu_r')


    extent = axis.get_window_extent().transformed(figure.dpi_scale_trans.inverted())
    plt.savefig((clip.filename + str("_.jpg")), format='jpg', bbox_inches=extent, pad_inches=0)
    plt.close()

Bu beni doğru yola soktu, ancak iki sorunum vardı: 1) Jupyter defterimde bir yazı tipi hatasını önlemek için dpi'yi 1'den büyük bir sayıya ayarlamak zorunda kaldım; ve 2) hala küçük bir sınır vardı, bu yüzden Bbox'ın boyutunu manuel olarak değiştirmem gerekiyor extent.get_points()*np.array([[1.1],[.9]]).
Bob Baxley

Bir başkasına yardımcı olabilecek cevabı yerine getirdiğin için teşekkürler.
GPrathap

3

Jupyter'de bunu yapmaya çalışan herkes için

 plt.axis('off')

 spec = plt.imshow

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

2

Yukarıdaki cevaplar, kenar boşluklarını ve dolguyu kaldırmakla ilgili olsa da, etiketleri kaldırmada benim için çalışmadı. Bu soruya daha sonra rastlayan herkes için işe yarayan şey şu:

Şu konumda depolanan dört görüntüden 2x2'lik bir alt noktalar ızgarası istediğinizi varsayarsak images:

matplotlib.pyplot.figure(figsize = (16,12)) # or whatever image size you require
for i in range(4):
    ax = matplotlib.pyplot.subplot(2,2,i+1)
    ax.axis('off')
    imshow(images[i])
matplotlib.pyplot.savefig(path, bbox_inches='tight')

1

Burada ipuçlarını kullanarak sınırdan da kurtulmaya çalıştım ama hiçbir şey gerçekten işe yaramadı. Biraz uğraştım ve yüz rengini değiştirmenin jupyter laboratuvarlarında bana sınır vermediğini buldum (Herhangi bir renk beyaz sınırdan kurtulmama neden oldu). Bu yardımcı olur umarım.

def show_num(data):
data = np.rot90(data.reshape((16,16)), k=3)
data = np.fliplr(data)
fig = plt.figure(frameon=False, facecolor='white')
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax.imshow(data)
plt.show()

görüntü açıklamasını buraya girin



0

Benim için bu kod, matehat , unutbu ve WHZW kodlarından çerçevesiz ve eksenler olmadan girdi görüntü boyutunu benzer hale getirdi :

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plt.axis('off')
viridis = cm.get_cmap('gist_gray', 256)
plt.imshow(data, aspect='auto', cmap=viridis)
plt.tight_layout()
plt.savefig(out_file, bbox_inches='tight', transparent=True, pad_inches=0)

Çalışma zamanı ortamı:
Python 3.6.10
Matplotlib 3.2.1
OS Windows 10

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.