2010-03-30 24 views
14

Estoy usando matplotlib para trazar imágenes normalizadas de registro, pero me gustaría que los datos de imagen brutos originales se representen en la barra de colores en lugar de el intervalo [0-1]. Me da la sensación de que hay una manera más matplotlib'y de hacer esto al usar algún tipo de objeto de normalización y no transformar los datos de antemano ... en cualquier caso, podría haber valores negativos en la imagen sin formato.¿Cómo puedo dibujar un diagrama imshow log-normalizado con una barra de colores que represente los datos brutos en matplotlib

import matplotlib.pyplot as plt 
import numpy as np 

def log_transform(im): 
    '''returns log(image) scaled to the interval [0,1]''' 
    try: 
     (min, max) = (im[im > 0].min(), im.max()) 
     if (max > min) and (max > 0): 
      return (np.log(im.clip(min, max)) - np.log(min))/(np.log(max) - np.log(min)) 
    except: 
     pass 
    return im 

a = np.ones((100,100)) 
for i in range(100): a[i] = i 
f = plt.figure() 
ax = f.add_subplot(111) 
res = ax.imshow(log_transform(a)) 
# the colorbar drawn shows [0-1], but I want to see [0-99] 
cb = f.colorbar(res) 

He intentado usar cb.set_array, pero eso no parece hacer nada, y cb.set_clim, sino que cambia la escala de los colores por completo.

+0

Así que al parecer me puede pasar una instancia de normalización en imshow y la imagen se normalizará para mí: res = ax.imshow (im, norma = mpl.colors.LogNorm()) Aún así, si adjunto una barra de color, los valores se establecen en vals normalizados en lugar de los datos brutos. –

Respuesta

27

Sí, lo hay! Use LogNorm. Aquí hay un extracto del código de una utilidad que escribí para mostrar matrices de confusión en una escala de registro.

from pylab import figure, cm 
from matplotlib.colors import LogNorm 
# C = some matrix 
f = figure(figsize=(6.2,5.6)) 
ax = f.add_axes([0.17, 0.02, 0.72, 0.79]) 
axcolor = f.add_axes([0.90, 0.02, 0.03, 0.79]) 
im = ax.matshow(C, cmap=cm.gray_r, norm=LogNorm(vmin=0.01, vmax=1)) 
t = [0.01, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0] 
f.colorbar(im, cax=axcolor, ticks=t, format='$%.2f$') 
f.show() 
+0

¡Gran respuesta! Pero, ¿por qué incluiste los $ símbolos en el formato de la penúltima línea? Si los deja fuera, las etiquetas de los ejes estarán en una fuente san-serif y coincidirán con el resto de las etiquetas de los ejes. – DanHickstein

+0

Buen punto; Probablemente solo copié y pegué desde el código existente. Me gusta laTeXize mi texto de la trama. –

6

Si lo que desea es la imagen que se log-normalizada (para resaltar los detalles), pero no los datos (para preservar los valores físicos), entonces se tienen que aplicar la transformación en el propio mapa de colores. Usted puede hacer eso con la cmap_map() la función dada en el libro de cocina: http://www.scipy.org/Cookbook/Matplotlib/ColormapTransformations

Cuestiones relacionadas