scipy: savefig tanpa bingkai, sumbu, hanya konten

92

Di numpy / scipy saya memiliki gambar yang disimpan dalam array. Saya dapat menampilkannya, saya ingin menyimpannya menggunakan savefig tanpa batas, sumbu, label, judul, ... Hanya gambar murni, tidak ada yang lain.

Saya ingin menghindari paket seperti PyPNGatau scipy.misc.imsave, terkadang bermasalah (tidak selalu terinstal dengan baik, hanya dasar savefig()bagi saya

Jakub M.
sumber

Jawaban:

115

EDIT

Berubah aspect='normalmenjadi aspect='auto'sejak itu berubah di versi matplotlib yang lebih baru (terima kasih kepada @ Luke19).


Asumsi :

import matplotlib.pyplot as plt

Untuk membuat sosok tanpa bingkai:

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

Untuk membuat konten mengisi seluruh gambar

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

Kemudian gambarlah gambar Anda di atasnya:

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

The aspectparameter mengubah ukuran pixel untuk memastikan mereka mengisi ukuran angka yang ditetapkan dalam fig.set_size_inches(…). Untuk merasakan bagaimana bermain dengan hal-hal semacam ini, bacalah dokumentasi matplotlib , khususnya tentang subjek Axes, Axis dan Artist.

matehat
sumber
4
tidak, saya masih memiliki beberapa perbatasan transparan kecil, dan yang saya inginkan adalah tidak ada perbatasan sama sekali , gambar murni
Jakub M.
5
Jika Anda secara manual mengatur wdan hparameter dalam fig.set_size_inches(w,h)dan dpiparameter dalam fig.savefig(fname, dpi)sehingga mengakibatkan 24px oleh 24px, itu harus bekerja dengan baik. Misalnya, w = h = 1dandpi = 24
matehat
5
Saya harus menggabungkan kedua jawaban ini, dan jawaban di bawah ini oleh Mostafa Pakparvar. Anda tidak hanya perlu mematikan sumbu, tetapi Anda juga perlu menyetel_visible menjadi false untuk memastikan white space menghilang. (wtf?)
Bryce Guinta
6
Baru saja mencoba ini menggunakan matplotlib v2.2.2 dan itu bekerja dengan sempurna (kecuali imshowsintaksnya diubah menjadi aspect='auto'bukan 'normal').
Luke19
2
Ini adalah pendekatan yang tepat. ax = plt.Axes(fig, [0., 0., 1., 1.])adalah yang membuatnya berhasil.
greatvovan
73

Solusi yang lebih mudah tampaknya:

fig.savefig('out.png', bbox_inches='tight', pad_inches=0)
katak cuaca
sumber
2
Ini berhasil dengan baik bagi saya. Juga, bantalan_ inci dapat diubah ke ukuran yang diinginkan dengan mudah. Terima kasih!
Curious2learn
27
Saya masih mendapat margin putih dengan ini.
Fábio Perez
3
Saya dapat memperbarui ini untuk versi yang lebih baru / masalah margin yang tersisa hanya dengan menambahkan transparent = True fig.savefig('out.png', bbox_inches='tight',transparent=True, pad_inches=0)
mdoc-2011
2
Masih punya sumbu dan tanda centang dan semuanya dengan ini :(
BjornW
3
Ini tidak melakukan apa-apa. Ini akan memberi Anda gambar dengan semua sumbu dan label.
1313e
27

Anda dapat menemukan bbox gambar di dalam sumbu (menggunakan get_window_extent), dan menggunakan bbox_inchesparameter untuk hanya menyimpan bagian gambar itu:

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)

Saya belajar trik ini dari Joe Kington di sini .

unutbu
sumber
6
hanya plt.axis('off')membantu. Jawaban lain tidak banyak membantu.
imsrgadich
3
Ini bekerja dengan cukup baik. Namun dalam kasus saya masih ada batas putih kecil. Ada ide tentang cara menghapus perbatasan ini?
pengguna3731622
@ user3731622, silakan coba plt.savefig('/temp/test.png', bbox_inches='tight', transparent=True, pad_inches=0)alih-alihplt.savefig('/tmp/test.png', bbox_inches=extent)
Cloud Cho
17

Saya telah mencoba beberapa opsi dalam kasus saya, dan solusi terbaik adalah ini:

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

lalu simpan gambar Anda dengan savefig

Cagri Sarigoz
sumber
1
Dari semua solusi ini, ini adalah satu-satunya solusi yang berhasil untuk saya.
Puff
8

Saya akan menyarankan jawaban heron13 dengan sedikit tambahan yang dipinjam dari sini untuk menghapus padding yang tersisa setelah mengatur bbox ke mode ketat, oleh karena itu:

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)
Mostafa Pakparvar
sumber
Saya mendapatkan pesan kesalahan yang mengatakan get_xaxis () dan get_yaxis () tidak ada. Tahu mengapa itu terjadi?
Jacob Malachowski
Buat objek axes (), lalu gunakan ax.xaxis dan ax.yaxis
perigon
Mendapat kesalahan yang mengatakan objek 'daftar' tidak memiliki atribut 'get_xaxis'
Haozhe Xie
7

Yang ini berhasil untuk saya

plt.savefig('filename',bbox_inches='tight',transparent=True, pad_inches=0)
Cathy Yang
sumber
3

Saya memiliki masalah yang sama saat melakukan beberapa visualisasi menggunakan librosa di mana saya ingin mengekstrak konten plot tanpa informasi lain. Jadi ini pendekatan saya. jawaban unutbu juga membantu saya untuk bekerja.

    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()
GPrathap
sumber
Ini membuat saya berada di jalur yang benar, tetapi saya memiliki dua masalah: 1) Saya harus mengatur dpi ke angka yang lebih besar dari 1 untuk menghindari kesalahan font di notebook jupyter saya; dan 2) masih ada batas kecil jadi saya harus mengubah tingkat Bbox secara manual extent.get_points()*np.array([[1.1],[.9]]).
Bob Baxley
terima kasih telah memenuhi jawaban yang dapat membantu orang lain.
GPrathap
3

Untuk siapa saja yang mencoba melakukan ini di Jupyter

 plt.axis('off')

 spec = plt.imshow

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

Sementara jawaban di atas membahas menghilangkan margin dan padding, mereka tidak berhasil untuk saya dalam menghapus label. Inilah yang berhasil, bagi siapa saja yang menemukan pertanyaan ini nanti:

Dengan asumsi Anda menginginkan petak subplot 2x2 dari empat gambar yang disimpan di 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')
ingin tahu
sumber
1

Saya mencoba menyingkirkan perbatasan juga, menggunakan tip di sini tetapi tidak ada yang berhasil. Beberapa mengotak-atik dan saya menemukan bahwa mengubah warna wajah tidak memberi saya batas di laboratorium jupyter (Warna apa pun menghasilkan menghilangkan batas putih). Semoga ini membantu.

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

masukkan deskripsi gambar di sini

Atom Scott
sumber
0

Bagi saya, kode ini dibuat serupa dengan ukuran gambar input tanpa bingkai dan sumbu dari kode matehat , unutbu , dan WHZW :

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)

Lingkungan runtime:
Python 3.6.10
Matplotlib 3.2.1
OS Windows 10

Cloud Cho
sumber