2010-03-30 2 views
14

Я использую matplotlib для построения изображений с нормированным логом, но я хотел бы, чтобы исходные данные необработанного изображения были представлены в цветовой полосе, а не интервал [0-1]. У меня возникает ощущение, что есть более матрепольный способ сделать это, используя какой-то объект нормализации, а не заранее преобразовывать данные ... в любом случае в необработанном изображении могут быть отрицательные значения.Как я могу нарисовать нормированный log-график imshow с цветной панелью, представляющей необработанные данные в 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) 

Я попытался с помощью cb.set_array, но это, кажется, не делать ничего, и cb.set_clim, но полностью перемасштабирует цвета.

+0

Таким образом, очевидно, я могу передать экземпляр нормализации в imshow и изображение будет нормализована для меня: Рез = ax.imshow (им, норма = mpl.colors.LogNorm()) Тем не менее, если я прикрепляю цветную панель, значения устанавливаются в нормализованные валы, а не в необработанные данные. –

ответ

27

Да, есть! Используйте LogNorm. Вот фрагмент кода из утилиты, которую я написал, чтобы отображать матрицы смешения на шкале журнала.

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

Отличный ответ! Но почему вы включили символы $ в формате на второй линии? Если вы их не заметите, метки осей будут иметь шрифт с сан-сериной и соответствовать остальным ярлыкам осей. – DanHickstein

+0

Хорошая точка; Скорее всего, я просто скопировал и вставил его из существующего кода. Мне нравится LaTeXize текст моего сюжета. –

6

Если вы просто хотите, чтобы изображение логарифмический нормированным (для усиления деталей), но не данные (для сохранения физических величин), то вы должны применить преобразование на самой палитре. Вы можете сделать это с помощью функции cmap_map(), приведенной в поваренной книге: http://www.scipy.org/Cookbook/Matplotlib/ColormapTransformations