Bagaimana cara menghilangkan celah antara subplot di matplotlib?

116

Kode di bawah ini menghasilkan celah di antara subplot. Bagaimana cara menghapus celah antara subplot dan membuat gambar menjadi kisi yang rapat?

masukkan deskripsi gambar di sini

import matplotlib.pyplot as plt

for i in range(16):
    i = i + 1
    ax1 = plt.subplot(4, 4, i)
    plt.axis('on')
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])
    ax1.set_aspect('equal')
    plt.subplots_adjust(wspace=None, hspace=None)
plt.show()
pengguna3006135
sumber
2
posting link dan dapat diedit masuk Nonetidak melakukan apa yang Anda pikirkan, itu berarti 'gunakan default'.
tacaswell
Saya mencoba menambahkan angka alih-alih 'Tidak Ada' tetapi ini tidak menyelesaikan masalah.
pengguna3006135
4
plt.subplots_adjust(wspace=0, hspace=0)akan menyelesaikan masalah Anda, jika bukan karena Anda menggunakan 'equal'aspek. Lihat jawaban saya untuk detailnya.
apdnu

Jawaban:

100

Anda dapat menggunakan gridspec untuk mengontrol jarak antar sumbu. Ada lebih banyak informasi di sini.

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

plt.figure(figsize = (4,4))
gs1 = gridspec.GridSpec(4, 4)
gs1.update(wspace=0.025, hspace=0.05) # set the spacing between axes. 

for i in range(16):
   # i = i + 1 # grid spec indexes from 0
    ax1 = plt.subplot(gs1[i])
    plt.axis('on')
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])
    ax1.set_aspect('equal')

plt.show()

sumbu sangat berdekatan

Molly
sumber
35
Ini tidak terbatas pada GridSpec, jika Anda mengambil gambar saat penciptaan, Anda juga dapat mengatur jarak dengan:fig.subplots_adjust(hspace=, wspace=)
Rutger Kassies
3
apa arti baris terakhir dalam forloop?
Ciprian Tomoiagă
Ini tip yang sangat bagus, tapi tidak berguna subplots. Jawaban ini menyelesaikan pekerjaan tanpa mengorbankan subplots.
wizclown
Apakah ada cara untuk menghilangkan jarak horizontal hanya antara baris pertama dan kedua dari sumbu?
Stefano
136

Masalahnya adalah penggunaan aspect='equal', yang mencegah subplot meregang ke rasio aspek arbitrer dan mengisi semua ruang kosong.

Biasanya, ini akan berhasil:

import matplotlib.pyplot as plt

ax = [plt.subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])

plt.subplots_adjust(wspace=0, hspace=0)

Hasilnya begini:

Namun, dengan aspect='equal', seperti pada kode berikut:

import matplotlib.pyplot as plt

ax = [plt.subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])
    a.set_aspect('equal')

plt.subplots_adjust(wspace=0, hspace=0)

Inilah yang kami dapatkan:

Perbedaan dalam kasus kedua ini adalah Anda memaksa sumbu x dan y memiliki jumlah unit / piksel yang sama. Karena sumbu berubah dari 0 ke 1 secara default (yaitu, sebelum Anda memplot apapun), menggunakan aspect='equal'gaya setiap sumbu menjadi persegi. Karena gambar tersebut bukan persegi, pyplot menambahkan spasi ekstra antara sumbu secara horizontal.

Untuk mengatasi masalah ini, Anda dapat mengatur gambar Anda agar memiliki rasio aspek yang benar. Kami akan menggunakan antarmuka pyplot berorientasi objek di sini, yang saya anggap lebih unggul secara umum:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8,8)) # Notice the equal aspect ratio
ax = [fig.add_subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])
    a.set_aspect('equal')

fig.subplots_adjust(wspace=0, hspace=0)

Inilah hasilnya:

apdnu
sumber
3
Terima kasih! jawaban Anda sederhana dan bekerja dengan sempurna. plt.subplots_adjust(wspace=0, hspace=0)
MohamedEzz
35

Tanpa menggunakan gridspec sepenuhnya, berikut ini mungkin juga digunakan untuk menghilangkan celah dengan mengatur wspace dan hspace ke nol:

import matplotlib.pyplot as plt

plt.clf()
f, axarr = plt.subplots(4, 4, gridspec_kw = {'wspace':0, 'hspace':0})

for i, ax in enumerate(f.axes):
    ax.grid('on', linestyle='--')
    ax.set_xticklabels([])
    ax.set_yticklabels([])

plt.show()
plt.close()

Yang menghasilkan:

.

Insinyur Gratis Herpes
sumber
4

Apakah Anda mencoba plt.tight_layout()?

dengan plt.tight_layout() masukkan deskripsi gambar di sini tanpa itu: masukkan deskripsi gambar di sini

Atau: sesuatu seperti ini (gunakan add_axes)

left=[0.1,0.3,0.5,0.7]
width=[0.2,0.2, 0.2, 0.2]
rectLS=[]
for x in left:
   for y in left:
       rectLS.append([x, y, 0.2, 0.2])
axLS=[]
fig=plt.figure()
axLS.append(fig.add_axes(rectLS[0]))
for i in [1,2,3]:
     axLS.append(fig.add_axes(rectLS[i],sharey=axLS[-1]))    
axLS.append(fig.add_axes(rectLS[4]))
for i in [1,2,3]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[8]))
for i in [5,6,7]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))     
axLS.append(fig.add_axes(rectLS[12]))
for i in [9,10,11]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))

Jika Anda tidak perlu berbagi sumbu, cukup axLS=map(fig.add_axes, rectLS) masukkan deskripsi gambar di sini

CT Zhu
sumber
Saya mencoba tata letak yang ketat, tetapi tidak menghilangkan celah, yang saya inginkan. Solusi gridspec berhasil. Terima kasih atas sarannya.
pengguna3006135
Ini bekerja dengan baik dalam hubungannya dengan saran-saran lainnya. tight_layout () membantu menghilangkan spasi di atas dan di samping plot yang tidak memiliki tujuan.
D mungkin
0

Dengan versi matplotlib terbaru, Anda mungkin ingin mencoba Constrained Layout . Namun ini tidak berfungsi plt.subplot(), jadi Anda perlu menggunakan plt.subplots():

fig, axs = plt.subplots(4, 4, constrained_layout=True)
Michel de Ruiter
sumber