2012-07-15 41 views
12

estoy generando matrices 2D sobre ejes espaciados logarítmicamente (por ejemplo, las coordenadas x de píxeles se generan utilizando logspace(log10(0.95), log10(2.08), n).ejes no lineales para imshow en matplotlib

Quiero mostrar la imagen utilizando un imshow llanura de edad, en su resolución y escalado nativo (no necesito to stretch it; los datos en sí ya están en escala de registro), pero quiero agregar ticks, etiquetas, líneas que están en el lugar correcto en los ejes de registro. ¿Cómo hago esto?

Idealmente podría usar los comandos de la línea axvline(1.5) y la línea estaría en el lugar correcto (58% desde la izquierda), pero si la única manera es traducir manualmente entre las coordenadas de la escala de log y la imagen c oordinates, eso está bien, también.

Para ejes lineales, usar extents= en la llamada para imshow hace lo que quiero, pero no veo una manera de hacer lo mismo con un eje de registro.

Ejemplo:

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

Este ejemplo no funciona, ya medida = sólo se aplica a escalas lineales, así que cuando lo hace axvline a 100, que no aparece en el centro. Me gustaría que el eje x muestre 10, 100, 1000 y axvline(100) para poner una línea en el centro en el punto 100, mientras que los píxeles permanecen igualmente espaciados.

+0

Puede tener algún código de trabajo o imagen de lo que quiere lograr. Otra pregunta es si usted es flexible sobre el uso de pcolor en lugar de imshow. – imsc

+0

@imsc: agregó un ejemplo. Creo que pcolor está bien. – endolith

Respuesta

7

En realidad, funciona bien. Estoy confundido.

Anteriormente recibía errores sobre "Las imágenes no son compatibles con ejes no lineales", por lo que hice esta pregunta. Pero ahora, cuando lo intento, funciona:

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

Esto es mejor que pcolor() y pcolormesh() porque

  1. no es terriblemente lento y
  2. se interpola bien sin artefactos engañosos cuando la imagen no es se muestra en la resolución nativa.
+2

Estoy igualmente confundido. Previamente, probé 'imshow' con' log' y no funcionó, sin embargo, ahora funciona perfectamente. – imsc

+2

Hemos encontrado que si elimina 'extent' no funcionará. Es decir, 'plt.imshow (Z, cmap = 'gris'); plt.xscale ('log') 'provoca el error. – Developer

+1

@developer tal vez porque la extensión predeterminada comienza en 0? – endolith

10

En mi opinión, es mejor utilizar pcolor y los valores regulares (no convertidos) xey. pcolor le da más flexibilidad y los ejes xey regulares son menos confusos.

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

Como pcolor es lenta, una solución más rápida es utilizar pcolormesh lugar.

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

Esto parece que resolvería mi problema. Aquí hay un ejemplo más simple que trata sobre lo que estaba tratando de resolver: https://gist.github.com/3124528 Entonces, ¿pcolor es como un imshow extremadamente lento que dibuja cada píxel como un rectángulo? No hay forma de hacer 'xscale ('log')' con imshow? – endolith

+0

'pcolormesh' parece una forma más rápida de hacer lo mismo. "pcolormesh usa un QuadMesh, una generalización más rápida de pcolor, pero con algunas restricciones". No estoy seguro de cuáles son esas restricciones, pero parece que funciona. – endolith

+0

'pcolormesh' parece ser una buena alternativa. Una de las restricciones es que no se puede usar con matrices de coordenadas enmascaradas. – imsc

Cuestiones relacionadas