2012-04-16 24 views
21

Sto creando una trama in python. C'è un modo per ridimensionare l'asse di un fattore? I comandi yscale e xscale mi consentono solo di disattivare la scala di registro.Modifica della scala di stampa di un fattore in matplotlib

Modifica:
Ad esempio. Se ho un grafico in cui le scale x vanno da 1 nm a 50 nm, la scala x va da 1x10^(- 9) a 50x10^(- 9) e voglio che cambi da 1 a 50. Quindi, I desidera che la funzione complotto per dividere i valori x immessi sul terreno per 10^(- 9)

+4

Yotam, sembra che tu abbia molte domande in sospeso a cui è stata data risposta, ma non hai ancora accettato una risposta. Si prega di accettare una risposta per le domande più vecchie o aggiungere ulteriori informazioni in modo che possiamo aiutarti! – Hooked

risposta

10

Invece di cambiare le zecche, perché non cambiare le unità, invece? Crea un array separato X di valori x le cui unità sono in nm. In questo modo, quando disegni i dati, è già nel formato corretto! Assicurati di aggiungere un xlabel per indicare le unità (che dovrebbe essere sempre comunque).

from pylab import * 

# Generate random test data in your range 
N = 200 
epsilon = 10**(-9.0) 
X = epsilon*(50*random(N) + 1) 
Y = random(N) 

# X2 now has the "units" of nanometers by scaling X 
X2 = (1/epsilon) * X 

subplot(121) 
scatter(X,Y) 
xlim(epsilon,50*epsilon) 
xlabel("meters") 

subplot(122) 
scatter(X2,Y) 
xlim(1, 50) 
xlabel("nanometers") 

show() 

enter image description here

+0

Questo è quello che voglio fare ora. Pensavo ci fosse un modo più elegante. – Yotam

5

per impostare l'intervallo di asse x, è possibile utilizzare set_xlim(left, right), here are the docs

Aggiornamento:

Sembra che tu voglia una trama identica, ma cambi solo i "valori di tick", puoi farlo ottenendo i valori di tick e quindi cambiandoli semplicemente in qualunque cosa tu voglia. Così per il vostro bisogno sarebbe come questo:

ticks = your_plot.get_xticks()*10**9 
your_plot.set_xticklabels(ticks) 
+0

A mio parere, xlim modifica l'intervallo della trama e non la modifica. Guarda il mio esempio – Yotam

+0

@Yotam - Quindi vuoi che il grafico sia identico, ma i valori sulle etichette in scala x cambieranno? – fraxel

+0

Soluzione sorprendentemente semplice. Tuttavia, trovo che questo si traduca in etichette con decimali, anche quando si utilizza un ticker che dovrebbe visualizzare solo numeri interi (ad esempio MultipleLocator o MaxNLocator). Ho scoperto che questo può essere risolto usando 'ticks.astype (int)' invece di 'ticks'. –

40

Come avete notato, xscale e yscale non supporta un semplice ridimensionamento lineare (purtroppo). Come alternativa alla risposta di Hooked, invece di fare scherzi con i dati, si può ingannare le etichette in questo modo:

ticks = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x*scale)) 
ax.xaxis.set_major_formatter(ticks) 

Un esempio completo che mostra sia x scala y:

import numpy as np 
import pylab as plt 
import matplotlib.ticker as ticker 

# Generate data 
x = np.linspace(0, 1e-9) 
y = 1e3*np.sin(2*np.pi*x/1e-9) # one period, 1k amplitude 

# setup figures 
fig = plt.figure() 
ax1 = fig.add_subplot(121) 
ax2 = fig.add_subplot(122) 
# plot two identical plots 
ax1.plot(x, y) 
ax2.plot(x, y) 

# Change only ax2 
scale_x = 1e-9 
scale_y = 1e3 
ticks_x = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x/scale_x)) 
ax2.xaxis.set_major_formatter(ticks_x) 

ticks_y = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x/scale_y)) 
ax2.yaxis.set_major_formatter(ticks_y) 

ax1.set_xlabel("meters") 
ax1.set_ylabel('volt') 
ax2.set_xlabel("nanometers") 
ax2.set_ylabel('kilovolt') 

plt.show() 

E infine ho i crediti per un quadro:

Left: ax1 no scaling, right: ax2 y axis scaled to kilo and x axis scaled to nano

si noti che, se si dispone di text.usetex: true come me, si consiglia di racchiudere il la bels in $, così: '${0:g}$'.

+0

Questa è probabilmente la risposta più corretta. Grazie @oystein – oche

+0

Questo è l'hack di cui abbiamo bisogno –

Problemi correlati