2011-10-13 17 views
11

definire i datimatplotlib: aggiungere secondo asse() con sfondo trasparente?

x = np.linspace(0,2*np.pi,100) 
y = 2*np.sin(x) 

trama

fig = plt.figure() 
ax = plt.axes() 
fig.add_subplot(ax) 
ax.plot(x,y) 

Aggiungi secondo asse

newax = plt.axes(axisbg='none') 

Mi dà ValueError: Unknown element o, anche se lo fa la stessa cosa di quello che sto per descrivere. Posso anche vedere che questo funziona (nessun errore) per fare la stessa cosa:

newax = plt.axes() 
fig.add_subplot(newax) 
newax.set_axis_bgcolor('none') 

Tuttavia, si scopre il colore della figura originale "grigio" (o qualunque sia il fondo cifra è) di fondo? Non capisco, perché pensavo che questo avrebbe reso newax trasparente ad eccezione degli assi e della scatola attorno alla figura. Anche se posso passare l'ordine, la stessa cosa:

plt.close('all') 
fig = plt.figure() 
newax = plt.axes() 
fig.add_subplot(newax) 
newax.set_axis_bgcolor('none') 
ax = plt.axes() 
fig.add_subplot(ax) 
ax.plot(x,y) 

Ciò è sorprendente, perché ho pensato che il fondo di uno sarebbe sovrapposto all'altro, ma in entrambi i casi è lo sfondo newax che sembra essere visibile (o almeno questo è il colore che vedo).

Cosa sta succedendo qui?

risposta

37

Lei non è in realtà l'aggiunta di nuovi assi.

Matplotlib rileva che c'è già una trama in quella posizione e il ritorno invece di una nuova assi dell'oggetto.

(controllare per credere. ax e newax sarà lo stesso oggetto.)

Probabilmente non un motivo per cui ci si vuole, ma ecco come lo faresti.

(Inoltre, non chiamare newax = plt.axes() e quindi chiamare fig.add_subplot(newax) Stai facendo la stessa cosa due volte.)

Edit: Con più recenti (?> = 1.2, credo) versioni di matplotlib, si può realizzare la stessa cosa come l'esempio di seguito utilizzando i label kwarg a fig.add_subplot. Per esempio. newax = fig.add_subplot(111, label='some unique string')

import matplotlib.pyplot as plt 

fig = plt.figure() 
ax = fig.add_subplot(1,1,1) 

# If you just call `plt.axes()` or equivalently `fig.add_subplot()` matplotlib 
# will just return `ax` again. It _won't_ create a new axis unless we 
# call fig.add_axes() or reset fig._seen 
newax = fig.add_axes(ax.get_position(), frameon=False) 

ax.plot(range(10), 'r-') 
newax.plot(range(50), 'g-') 
newax.axis('equal') 

plt.show() 

enter image description here

Naturalmente, questo sembra terribile, ma è quello che stai chiedendo ...

sto cercando di indovinare dalle vostre domande precedenti che si vuole solo aggiungere un secondo asse x? Se è così, questa è una cosa completamente diversa.

Se si desidera che le assi Y legati, quindi fare qualcosa di simile (un po 'prolissa ...):

import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 
newax = ax.twiny() 

# Make some room at the bottom 
fig.subplots_adjust(bottom=0.20) 

# I'm guessing you want them both on the bottom... 
newax.set_frame_on(True) 
newax.patch.set_visible(False) 
newax.xaxis.set_ticks_position('bottom') 
newax.xaxis.set_label_position('bottom') 
newax.spines['bottom'].set_position(('outward', 40)) 

ax.plot(range(10), 'r-') 
newax.plot(range(21), 'g-') 

ax.set_xlabel('Red Thing') 
newax.set_xlabel('Green Thing') 

plt.show() 

enter image description here

Se si desidera avere una nascosta, non collegato asse y, e uno completamente nuovo asse x, allora si farebbe qualcosa di simile:

import matplotlib.pyplot as plt 
import numpy as np 

fig, ax = plt.subplots() 
fig.subplots_adjust(bottom=0.2) 

newax = fig.add_axes(ax.get_position()) 
newax.patch.set_visible(False) 
newax.yaxis.set_visible(False) 

for spinename, spine in newax.spines.iteritems(): 
    if spinename != 'bottom': 
     spine.set_visible(False) 

newax.spines['bottom'].set_position(('outward', 25)) 

ax.plot(range(10), 'r-') 

x = np.linspace(0, 6*np.pi) 
newax.plot(x, 0.001 * np.cos(x), 'g-') 

plt.show() 

enter image description here

Nota che i valori Y per nulla tracciati su newax non vengono mai mostrati.

Se si volesse, si potrebbe anche prendere questo un ulteriore passo avanti, e hanno assi X e Y indipendenti (io non sono abbastanza sicuro che cosa sarebbe il punto di esso, ma sembra pulito ...):

import matplotlib.pyplot as plt 
import numpy as np 

fig, ax = plt.subplots() 
fig.subplots_adjust(bottom=0.2, right=0.85) 

newax = fig.add_axes(ax.get_position()) 
newax.patch.set_visible(False) 

newax.yaxis.set_label_position('right') 
newax.yaxis.set_ticks_position('right') 

newax.spines['bottom'].set_position(('outward', 35)) 

ax.plot(range(10), 'r-') 
ax.set_xlabel('Red X-axis', color='red') 
ax.set_ylabel('Red Y-axis', color='red') 

x = np.linspace(0, 6*np.pi) 
newax.plot(x, 0.001 * np.cos(x), 'g-') 

newax.set_xlabel('Green X-axis', color='green') 
newax.set_ylabel('Green Y-axis', color='green') 


plt.show() 

enter image description here

si può anche solo aggiungere un ulteriore colonna vertebrale nella parte inferiore della trama. A volte questo è più facile, specialmente se non vuoi zecche o cose numeriche. Non collegare una delle mie risposte troppo, ma c'è un esempio di quella qui: How do I plot multiple X or Y axes in matplotlib?

Come un'ultima cosa, essere sicuri di guardare il parasite axes examples se si desidera avere i diversi assi X e Y collegate attraverso un trasformazione specifica.

+0

Sì, in effetti si trattava dei due assi ... Non stavo ottenendo il 'twinx' e ora' twiny' (suppongo che avrei dovuto sapere che il secondo esisteva) ma non pensavo fosse necessario che loro avessero bisogno essere "linkato", necessariamente, purché la larghezza della trama fosse la stessa (perché posso semplicemente impostare i limiti uguali a quelli). – hatmatrix

+0

Quindi, se fossi disposto a farlo, questo primo esempio potrebbe anche funzionare disattivando la visibilità delle altre spine. Sembra che ci siano così tante varianti su ogni metodo in matplotlib che stavo andando per alcune funzioni "generali" che possono essere applicate nella maggior parte dei casi, senza dover imparare ognuna delle funzioni di "convenienza" disponibili ... ma grazie, questo risolve qualunque cosa. Ma il plt.axes() che restituisce lo stesso oggetto è stato una sorpresa - ho pensato che fosse ciò per cui è plt.gca(). E questo è diverso da Matlab ... – hatmatrix

+0

Bene, 'plt.axes()' crea un nuovo asse in qualsiasi altra circostanza. Ha solo un pezzo di codice che controlla se c'è già un asse in quella posizione, e lo restituisce (e lo rende l'asse corrente) se è così. (Fondamentalmente, questo è il terzo punto nella documentazione per 'plt.axes()', sebbene tu debba leggere un po 'tra le righe ...) –