2014-10-08 166 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 
))