2012-07-15 15 views
12

sto generando matrici 2D su assi log-distanziati (per esempio, le coordinate x pixel vengono generati utilizzando logspace(log10(0.95), log10(2.08), n).assi non lineari per imshow in matplotlib

voglio visualizzare l'immagine utilizzando un semplice vecchio imshow, nella sua risoluzione e scalabilità nativa (non ho bisogno di to stretch it, i dati stessi sono già log ridimensionati), ma voglio aggiungere zecche, etichette, linee che si trovano nella posizione corretta sugli assi del registro.

Idealmente, potrei semplicemente usare la riga di comando axvline(1.5) e la linea sarebbe nella posizione corretta (58% da sinistra), ma se l'unico modo è tradurre manualmente tra le coordinate di logscale e l'immagine c Oordinati, va bene anche questo.

Per gli assi lineari, utilizzare extents= nella chiamata a imshow fa ciò che voglio, ma non vedo un modo per fare la stessa cosa con un asse di registro.

Esempio:

from matplotlib.colors import LogNorm 

x = logspace(log10(10), log10(1000), 5) 
imshow(vstack((x,x)), extent=[10, 1000, 0, 100], cmap='gray', norm=LogNorm(), interpolation='nearest') 
axvline(100, color='red') 

Questo esempio non funziona, perché misura = vale solo per scale lineari, in modo che quando si fa axvline a 100, non risulta al centro. Mi piacerebbe che l'asse x mostrasse 10, 100, 1000 e axvline(100) per mettere una linea al centro nel punto 100, mentre i pixel rimangono equidistanti.

+0

Puoi avere qualche codice o immagine funzionante di ciò che desideri ottenere. Un'altra domanda è se sei flessibile sull'uso di pcolor invece di imshow. – imsc

+0

@imsc: aggiunto un esempio. Penso che pcolor stia bene. – endolith

risposta

7

In realtà, funziona correttamente. Non ho capito bene.

Precedentemente ricevevo errori su "Le immagini non sono supportate su assi non lineari" ed è per questo che ho fatto questa domanda. Ma ora quando provo, funziona:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.logspace(1, 3, 5) 
y = np.linspace(0, 2, 3) 
z = np.linspace(0, 1, 4) 
Z = np.vstack((z, z)) 

plt.imshow(Z, extent=[10, 1000, 0, 1], cmap='gray') 
plt.xscale('log') 

plt.axvline(100, color='red') 

plt.show() 

Questo è meglio di pcolor() e pcolormesh() perché

  1. non è follemente lento e
  2. viene interpolato bene senza artefatti fuorvianti quando l'immagine non è mostrato a risoluzione nativa.
+2

Sono ugualmente confuso. In precedenza, ho provato 'imshow' con' log' e non ha funzionato, tuttavia funziona perfettamente ora. – imsc

+2

Abbiamo scoperto che se rimuovi 'extent' non funzionerà. Cioè, 'plt.imshow (Z, cmap = 'gray'); plt.xscale ('log') 'solleva l'errore. – Developer

+1

@developer oh forse perché l'estensione predefinita inizia da 0? – endolith

10

A mio avviso, è preferibile utilizzare pcolor e valori regolari x (non convertiti) xey. pcolor offre maggiore flessibilità e l'asse xey regolare è meno confuso.

import pylab as plt 
import numpy as np 
from matplotlib.colors import LogNorm 
from matplotlib.ticker import LogFormatterMathtext 

x=np.logspace(1, 3, 6) 
y=np.logspace(0, 2,3) 
X,Y=np.meshgrid(x,y) 
z = np.logspace(np.log10(10), np.log10(1000), 5) 
Z=np.vstack((z,z)) 

im = plt.pcolor(X,Y,Z, cmap='gray', norm=LogNorm()) 
plt.axvline(100, color='red') 

plt.xscale('log') 
plt.yscale('log') 

plt.colorbar(im, orientation='horizontal',format=LogFormatterMathtext()) 
plt.show() 

enter image description here

Come pcolor è lento, una soluzione più veloce è quello di utilizzare pcolormesh invece.

im = plt.pcolormesh(X,Y,Z, cmap='gray', norm=LogNorm()) 
+0

Sembra che risolverebbe il mio problema. Ecco un esempio più semplice che ottiene quello che stavo cercando di risolvere: https://gist.github.com/3124528 Quindi pcolor è come un imshow estremamente lento che disegna ogni pixel come un rettangolo? Non c'è modo di fare 'xscale ('log')' con imshow? – endolith

+0

'pcolormesh' sembra un modo più veloce per fare la stessa cosa. "pcolormesh usa un QuadMesh, una generalizzazione più veloce di pcolor, ma con alcune restrizioni." Non sono sicuro di quali siano queste restrizioni, ma sembra funzionare. – endolith

+0

'pcolormesh' sembra essere una bella alternativa. Una delle restrizioni è che non può essere utilizzato con gli array di coordinate mascherati. – imsc

Problemi correlati