2014-10-08 2 views
2

Возможно ли определить цветовой палитру matplitlib, которая логарифмически интерполируется между двумя заданными цветами?Логарифмическая цветовая палитра в matplotlib

фон: При построении массивов в Matplotlib с помощью команды imshow(...), цветовых карт используются, чтобы назначить цвет каждого значение данных. Часто предопределенные цветовые карты используются от matplotlib.cm, но также могут быть созданы более расширенные цветовые карты с использованием matplotlib.colors.LinearSegmentedColormap. Как правило, в этих цветовых картах значение цвета линейно изменяется со значением данных.

Подсказка: Мой вопрос не, как построить массив логарифмически. Обычно это делается путем сохранения линейной цветовой схемы и некоторых трюков (либо путем построения графика log(array) и замены меток x на цветной панели на 10^x, либо путем явного изменения поведения нормализации команды plot). Здесь я явно нуждаюсь в экземпляре colormap.

+0

Так что 'imshow (data, norm = matplotlib.colors.LogNorm())' не то, что вы ищете? Это делает то, что вы описываете в своем намеке. Это то, что вы хотите построить массив логарифмически, но имеет ли линейный график colorbar? – burnpanck

+0

@burnpanck нет, вот что я делаю * не * хочу, мне нужен автономный экземпляр colormap, который работает логарифмически. Причина в том, что я использую другое программное обеспечение, которое создает графики с использованием matplotlib colormaps. – flonk

+0

Хорошо, какое программное обеспечение, каким образом вы передаете ему цветовой код? Причина в том, что довольно легко написать собственный подкласс класса «Colormap», который просто обертывает другой цветовой код, применяя преобразование линейного преобразования в журнал. Однако неясно, можно ли передать такой пользовательский класс. – burnpanck

ответ

2

Вы можете предоставить подделку Colormap, которая применяет желаемую нормализацию, прежде чем передавать ее в реальную цветовую палитру. Вот такая реализация Colormap:

import matplotlib as mpl 

class ReNormColormapAdaptor(mpl.colors.Colormap): 
    """ Colormap adaptor that uses another Normalize instance 
    for the colormap than applied to the mappable. """ 
    def __init__(self,base,cmap_norm,orig_norm=None): 
     if orig_norm is None: 
      if isinstance(base,mpl.cm.ScalarMappable): 
       orig_norm = base.norm 
       base = base.cmap 
      else: 
       orig_norm = mpl.colors.Normalize(0,1) 
     self._base = base 
     if (
      isinstance(cmap_norm,type(mpl.colors.Normalize)) 
      and issubclass(cmap_norm,mpl.colors.Normalize) 
     ): 
      # a class was provided instead of an instance. create an instance 
      # with the same limits. 
      cmap_norm = cmap_norm(orig_norm.vmin,orig_norm.vmax) 
     self._cmap_norm = cmap_norm 
     self._orig_norm = orig_norm 

    def __call__(self, X, **kwargs): 
     """ Re-normalise the values before applying the colormap. """ 
     return self._base(self._cmap_norm(self._orig_norm.inverse(X)),**kwargs) 

    def __getattr__(self,attr): 
     """ Any other attribute, we simply dispatch to the underlying cmap. """ 
     return getattr(self._base,attr) 

Поскольку значения он получает уже будет нормирована на [0,1), он должен знать, что предыдущие нормализации, чтобы отменить его (с учетом как orig_norm). Оставьте пустым, если вы хотите применить цветовую палитру для unnormalised значений:

cmap = ReNormColormapAdaptor(mpl.cm.jet,mpl.colors.LogNorm(vmin,vmax)) 

Если у вас уже есть ScalarMappable, то вы можете передать его вместо этого палитры, откуда как Colormap, предыдущая нормализация и будут приняты новые предельные нормативы:

import matplotlib.pyplot as plt 

scalar_mappable = plt.imshow(C); 
scalar_mappable.set_cmap(ReNormColormapAdaptor(
    scalar_mappable, 
    mpl.colors.LogNorm 
)) 
Смежные вопросы