2014-10-08 88 views
2

是否可以定义在两种给定颜色之间对数插值的matplitlib颜色映射?matplotlib中的对数颜色映射

背景:当通过imshow(...)命令绘制在matplotlib阵列,的colormaps用于分配一种颜色给每个数据值。通常,从matplotlib.cm开始使用预定义的色彩映射,但也可以使用matplotlib.colors.LinearSegmentedColormap创建更多增强的色彩映射。 通常,在这些色彩映射中,色彩值随数据值线性变化。

提示:我的问题是,如何对数绘制的数组。这通常是通过保持线性颜色表和一些技巧(通过绘制log(array)并将颜色栏上的x替换为10^x,或通过明确地改变绘图命令的标准化行为来完成)。在这里,我明确需要colormap实例。

+0

因此'imshow(data,norm = matplotlib.colors.LogNorm())'不是您要查找的内容吗?这基本上就是你在提示中描述的。难道你想要以对数形式绘制数组,但是将颜色条线性绘制? – burnpanck 2014-10-08 10:19:57

+0

@burnpanck否,这就是我所做的*不*想要的,我需要一个自主的色彩地图实例,它以对数形式工作。原因是我使用了一个使用matplotlib colormaps产生图的不同软件。 – flonk 2014-10-08 11:58:19

+0

好的,什么样的软件,以什么方式将颜色映射传递给它?原因是,可以很容易地编写一个自定义的'Colormap'子类,它只是包装另一个色彩映射表,应用线性到日志转换。但是,目前尚不清楚这样的自定义类是否可以通过。 – burnpanck 2014-10-08 13:48:59

回答

2

您可以提供一个假的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,那么你可以通过它的颜色表,从代替其中两个色彩映射表,以前的归一化和将会采取新的标准化限制:

import matplotlib.pyplot as plt 

scalar_mappable = plt.imshow(C); 
scalar_mappable.set_cmap(ReNormColormapAdaptor(
    scalar_mappable, 
    mpl.colors.LogNorm 
))