Come rimuovere gli spazi tra le sottotrame in matplotlib?


116

Il codice seguente produce spazi tra le sottotrame. Come rimuovo gli spazi tra le sottotrame e trasformo l'immagine in una griglia stretta?

inserisci qui la descrizione dell'immagine

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

2
inserisci un link e può essere modificato. Nonenon sta facendo quello che pensi, significa "usa il valore predefinito".
tacaswell

Ho provato ad aggiungere numeri invece di "Nessuno" ma questo non ha risolto il problema.
user3006135

4
plt.subplots_adjust(wspace=0, hspace=0)risolverebbe il tuo problema, se non fosse per il fatto che usi l' 'equal'aspetto. Vedi la mia risposta per i dettagli.
apdnu

Risposte:


100

È possibile utilizzare gridspec per controllare la spaziatura tra gli assi. Ci sono maggiori informazioni qui.

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

assi molto ravvicinati


35
Non è limitato a GridSpec, se prendi la cifra alla creazione puoi anche impostare le distanze con:fig.subplots_adjust(hspace=, wspace=)
Rutger Kassies

3
cosa significa essere l'ultima riga del forciclo?
Ciprian Tomoiagă

Questo è un suggerimento molto carino, ma non usa subplots. Questa risposta porta a termine il lavoro senza sacrificare subplots.
wizclown

C'è un modo per rimuovere la spaziatura orizzontale solo tra la prima e la seconda fila di assi?
Stefano

136

Il problema è l'uso di aspect='equal', che impedisce alle sottotrame di allungarsi a proporzioni arbitrarie e riempire tutto lo spazio vuoto.

Normalmente, questo funzionerebbe:

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)

Il risultato è questo:

Tuttavia, con aspect='equal', come nel codice seguente:

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)

Questo è ciò che otteniamo:

La differenza in questo secondo caso è che hai forzato gli assi xey per avere lo stesso numero di unità / pixel. Poiché gli assi vanno da 0 a 1 per impostazione predefinita (cioè prima di tracciare qualsiasi cosa), l'uso aspect='equal'forza ogni asse di essere un quadrato. Poiché la figura non è un quadrato, il pyplot aggiunge una spaziatura extra tra gli assi orizzontalmente.

Per aggirare questo problema, puoi impostare la tua figura in modo che abbia le proporzioni corrette. Useremo l'interfaccia pyplot orientata agli oggetti qui, che considero superiore in generale:

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)

Ecco il risultato:


3
Grazie! la tua risposta è semplice e funziona perfettamente. plt.subplots_adjust(wspace=0, hspace=0)
MohamedEzz

35

Senza ricorrere interamente a gridspec , è possibile utilizzare anche quanto segue per rimuovere le lacune impostando wspace e hspace a zero:

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

Con il risultato di:

.


4

Hai provato plt.tight_layout()?

con plt.tight_layout() inserisci qui la descrizione dell'immagine senza: inserisci qui la descrizione dell'immagine

Oppure: qualcosa di simile (usa 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]))

Se non hai bisogno di condividere gli assi, allora semplicemente axLS=map(fig.add_axes, rectLS) inserisci qui la descrizione dell'immagine


Ho provato un layout stretto, ma non ho eliminato gli spazi vuoti, che è quello che voglio. La soluzione gridspec ha funzionato. Grazie per i suggerimenti.
user3006135

Funzionava benissimo insieme agli altri suggerimenti. tight_layout () ha aiutato a rimuovere lo spazio bianco sopra e ai lati della trama che non serviva a nulla.
DC Forse il

0

Con le recenti versioni di matplotlib potresti voler provare Constrained Layout . plt.subplot()Tuttavia, questo non funziona , quindi è necessario utilizzare plt.subplots()invece:

fig, axs = plt.subplots(4, 4, constrained_layout=True)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.