2010-07-08 16 views
17

Quando ho eseguito questo codiceCreazione di sottotrame quadrati (di uguale altezza e larghezza) in matplotlib

from pylab import * 

figure() 
ax1 = subplot(121) 
plot([1, 2, 3], [1, 2, 3]) 
subplot(122, sharex=ax1, sharey=ax1) 
plot([1, 2, 3], [1, 2, 3]) 
draw() 
show() 

ottengo due sottotrame che sono "schiacciati" nella dimensione X. Come posso ottenere queste sottotrame in modo che l'altezza dell'asse Y sia uguale alla larghezza dell'asse X, per entrambe le sottotrame?

Sto usando matplotlib v.0.99.1.2 su Ubuntu 10.04.

Aggiornamento 2010-07-08: Diamo un'occhiata ad alcune cose che non funzionano.

Dopo aver cercato su Google tutto il giorno, ho pensato che potesse essere correlato al ridimensionamento automatico. Così ho provato a giocherellare con quello.

from pylab import * 

figure() 
ax1 = subplot(121, autoscale_on=False) 
plot([1, 2, 3], [1, 2, 3]) 
subplot(122, sharex=ax1, sharey=ax1) 
plot([1, 2, 3], [1, 2, 3]) 
draw() 
show() 

matplotlib insiste sull'auto-ridimensionamento.

from pylab import * 

figure() 
ax1 = subplot(121, autoscale_on=False) 
plot([1, 2, 3], [1, 2, 3]) 
subplot(122, sharex=ax1, sharey=ax1, autoscale_on=False) 
plot([1, 2, 3], [1, 2, 3]) 
draw() 
show() 

In questo, i dati scompare completamente. WTF, matplotlib? Solo WTF?

Ok, beh, forse se ripariamo le proporzioni?

from pylab import * 

figure() 
ax1 = subplot(121, autoscale_on=False) 
plot([1, 2, 3], [1, 2, 3]) 
axes().set_aspect('equal') 
subplot(122, sharex=ax1, sharey=ax1) 
plot([1, 2, 3], [1, 2, 3]) 
draw() 
show() 

Questo provoca la scomparsa del primo sottotramma. È divertente! Chi è venuto con quello?

In tutta serietà, ora ... dovrebbe essere davvero una cosa così difficile da realizzare?

risposta

16

Il tuo problema nel definire l'aspetto delle trame è in arrivo quando si utilizza sharex e sharey.

Una soluzione è quella di non utilizzare gli assi condivisi. Ad esempio, si potrebbe fare questo:

from pylab import * 

figure() 
subplot(121, aspect='equal') 
plot([1, 2, 3], [1, 2, 3]) 
subplot(122, aspect='equal') 
plot([1, 2, 3], [1, 2, 3]) 
show() 

Tuttavia, una soluzione migliore è quella di cambiare il "regolabile" keywarg ... Volete = regolabili 'box', ma quando sei con assi comuni, si è essere regolabile = 'datalim' (e impostarlo su 'box' dà un errore).

Tuttavia, esiste una terza opzione per adjustable per gestire esattamente questo caso: adjustable="box-forced".

Ad esempio:

from pylab import * 

figure() 
ax1 = subplot(121, aspect='equal', adjustable='box-forced') 
plot([1, 2, 3], [1, 2, 3]) 
subplot(122, aspect='equal', adjustable='box-forced', sharex=ax1, sharey=ax1) 
plot([1, 2, 3], [1, 2, 3]) 
show() 

O in stile più moderno (nota: questa parte della risposta non avrebbe funzionato nel 2010):

import matplotlib.pyplot as plt 

fig, axes = plt.subplots(ncols=2, sharex=True, sharey=True) 
for ax in axes: 
    ax.plot([1, 2, 3], [1, 2, 3]) 
    ax.set(adjustable='box-forced', aspect='equal') 

plt.show() 

In entrambi i casi, si otterrà qualcosa di simile a:

enter image description here

+0

uso asse ('uguale') per più MATLAB come synthax. E quando l'aspetto deve essere 1 come "asse quadrato" in MATLAB, io uso figura (1, figsize = (6, 6)). – otterb

+0

Sfortunatamente, gli assi delle azioni sono spariti e bisogna rimuovere a mano i ticklabels. Questo è sfortunato :(. Che cosa, tipo di lavoro sta usando 'subplot_kw = {'adjustable': 'box-forced', 'aspect': 'equal'}' come opzione per 'subplot'. Solo problema ora è quello le etichette degli assi sono ancora mostrate per gli assi "condivisi" ... – rubenvb

+0

OK ... dove hai trovato la descrizione API 'adjustable = 'box-forced''? Sto diventando un po' pazzo qui ... – Atcold

2

dare una prova:

from pylab import * 

figure() 
ax1 = subplot(121, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3]) 
plot([1, 2, 3], [1, 2, 3]) 
##axes().set_aspect('equal') 
ax2 = subplot(122, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3]) 
plot([1, 2, 3], [1, 2, 3]) 
draw() 
show() 

ho commentato la linea axes() come che creare una nuova axes in una posizione arbitraria, piuttosto che un subplot prefabbricato con una posizione calcolata.

La chiamata subplot crea effettivamente un'istanza Axes, il che significa che può utilizzare le stesse proprietà di una Axes.

Spero che questo aiuta :)

Problemi correlati