Cambiar valores en el eje del gráfico matplotlib imshow ()

89

Digamos que tengo algunos datos de entrada:

data = np.random.normal(loc=100,scale=10,size=(500,1,32))
hist = np.ones((32,20)) # initialise hist
for z in range(32):
    hist[z],edges = np.histogram(data[:,0,z],bins=np.arange(80,122,2))

Puedo trazarlo usando imshow():

plt.imshow(hist,cmap='Reds')

consiguiendo:

ingrese la descripción de la imagen aquí

Sin embargo, los valores del eje x no coinciden con los datos de entrada (es decir, media de 100, rango de 80 a 122). Por lo tanto, me gustaría cambiar el eje x para mostrar los valores en edges.

Yo he tratado:

ax = plt.gca()
ax.set_xlabel([80,122]) # range of values in edges
...
# this shifts the plot so that nothing is visible

y

ax.set_xticklabels(edges)
...
# this labels the axis but does not centre around the mean:

ingrese la descripción de la imagen aquí

¿Alguna idea sobre cómo puedo cambiar los valores del eje para reflejar los datos de entrada que estoy usando?

atomh33ls
fuente
Use en pcolorlugar de imshowcomo se menciona en esta respuesta .
Nirmal

Respuestas:

142

Intentaría evitar cambiar el xticklabelssi es posible; de ​​lo contrario, puede resultar muy confuso si, por ejemplo, traza su histograma con datos adicionales.

Definir el rango de su cuadrícula es probablemente lo mejor y con imshowél se puede hacer agregando la extentpalabra clave. De esta forma los ejes se ajustan automáticamente. Si desea cambiar las etiquetas, usaría set_xticksquizás con algún formateador. Modificar las etiquetas directamente debería ser el último recurso.

fig, ax = plt.subplots(figsize=(6,6))

ax.imshow(hist, cmap=plt.cm.Reds, interpolation='none', extent=[80,120,32,0])
ax.set_aspect(2) # you may also use am.imshow(..., aspect="auto") to restore the aspect ratio

ingrese la descripción de la imagen aquí

Rutger Kassies
fuente
18
También vale la pena señalar que interpolation="none"aquí se utilizó una representación mucho más precisa de datos reales.
Enganchado el
4
Una respuesta muy útil; Lo he usado para hacer un diagrama de color de una función de dos variables (es decir, datos sísmicos). También agregué la opción "aspecto = 'auto'" en imshow () para poder 'estirar y apretar' la pantalla sísmica.
Kurt Peek
10

Tuve un problema similar y Google me estaba enviando a esta publicación. Mi solución fue un poco diferente y menos compacta, pero espero que esto pueda ser útil para alguien.

Mostrar su imagen con matplotlib.pyplot.imshow es generalmente una forma rápida de mostrar datos 2D. Sin embargo, esto por defecto etiqueta los ejes con el número de píxeles. Si los datos 2D que está trazando corresponden a una cuadrícula uniforme definida por las matrices xey, entonces puede usar matplotlib.pyplot.xticks y matplotlib.pyplot.yticks para etiquetar los ejes xey usando los valores en esas matrices. Estos asociarán algunas etiquetas, correspondientes a los datos reales de la cuadrícula, a los recuentos de píxeles en los ejes. Y hacer esto es mucho más rápido que usar algo como pcolor, por ejemplo.

Aquí hay un intento de esto con sus datos:

import matplotlib.pyplot as plt

# ... define 2D array hist as you did

plt.imshow(hist, cmap='Reds')
x = np.arange(80,122,2) # the grid to which your data corresponds
nx = x.shape[0]
no_labels = 7 # how many labels to see on axis x
step_x = int(nx / (no_labels - 1)) # step between consecutive labels
x_positions = np.arange(0,nx,step_x) # pixel count at label position
x_labels = x[::step_x] # labels you want to see
plt.xticks(x_positions, x_labels)
# in principle you can do the same for y, but it is not necessary in your case
rxs
fuente