【问题标题】:Nonlinear colormap with Matplotlib使用 Matplotlib 的非线性颜色图
【发布时间】:2016-02-25 16:45:33
【问题描述】:

我有一些数据,我想使用非线性颜色图使用 contourf/tricontourf 进行绘制。

我找到了一个脚本(见下文),只要级别介于 0 和正数之间,它就可以为颜色图提供很好的解决方案。

但是,我的数据是负数(-50 到 0 之间的水平)。不幸的是,根据我的情况调整级别根本不起作用(见图,子图 3)。那么有什么我需要考虑的吗?有没有人对我有任何建议,或者甚至可能面临同样的问题?

非常感谢您的帮助。

from pylab import *
from numpy import *
from matplotlib.colors import LinearSegmentedColormap

class nlcmap(LinearSegmentedColormap):
    """A nonlinear colormap"""

    name = 'nlcmap'

    def __init__(self, cmap, levels):
        self.cmap = cmap
        self.monochrome = self.cmap.monochrome
        self.levels = asarray(levels, dtype='float64')
        self._x = self.levels/ self.levels.max()
        self.levmax = self.levels.max()
        self.levmin = self.levels.min()
        self._y = linspace(self.levmin, self.levmax, len(self.levels))

    def __call__(self, xi, alpha=1.0, **kw):
        yi = interp(xi, self._x, self._y)
        return self.cmap(yi/self.levmax, alpha)

if __name__ == '__main__':

    y, x = mgrid[0.0:3.0:100j, 0.0:5.0:100j]
    H = 50.0 * exp( -(x**2 + y**2) / 4.0 )
    levels = [0, 1, 2, 3, 6, 9, 20, 50]

    H1 = -50.0 * exp( -(x**2 + y**2) / 4.0 )
    levels1 = [-50, -20, -9, -6, -3, -2, -1, 0]

    cmap_lin = cm.jet
    cmap_nonlin = nlcmap(cmap_lin, levels)
    cmap_lin1 = cm.jet
    cmap_nonlin1 = nlcmap(cmap_lin1, levels1)

    subplot(4,1,1)
    contourf(x, y, H, levels, cmap=cmap_nonlin)
    colorbar()
    subplot(4,1,2)
    contourf(x, y, H, levels, cmap=cmap_lin)
    colorbar()
    subplot(4,1,3)
    contourf(x, y, H1, levels1, cmap=cmap_nonlin1)
    colorbar()
    subplot(4,1,4)
    contourf(x, y, H1, levels1, cmap=cmap_lin1)
    colorbar()

    plt.show()  

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    问题似乎是您尝试通过除以最大值来投影 [0, 1] 范围内的值,这适用于最大值的正值,但不适用于负值...试试这个:

    from pylab import *
    from numpy import *
    from matplotlib.colors import LinearSegmentedColormap
    
    class nlcmap(LinearSegmentedColormap):
        """A nonlinear colormap"""
    
        name = 'nlcmap'
    
        def __init__(self, cmap, levels):
            self.cmap = cmap
            self.monochrome = self.cmap.monochrome
            self.levels = asarray(levels, dtype='float64')
            self.levmax = self.levels.max()
            self.levmin = self.levels.min()
            self._x = (self.levels - self.levmin) / (self.levmax - self.levmin)
            self._y = linspace(0, 1, len(self.levels))
    
        def __call__(self, xi, alpha=1.0, **kw):
            yi = interp(xi, self._x, self._y)
            return self.cmap(yi, alpha)
    
    if __name__ == '__main__':
    
        y, x = mgrid[0.0:3.0:100j, 0.0:5.0:100j]
        H = 50.0 * exp( -(x**2 + y**2) / 4.0 )
        levels = [0, 1, 2, 3, 6, 9, 20, 50]
    
        H1 = -50.0 * exp( -(x**2 + y**2) / 4.0 )
        levels1 = [-50, -20, -9, -6, -3, -2, -1, 0]
    
        cmap_lin = cm.jet
        cmap_nonlin = nlcmap(cmap_lin, levels)
        cmap_lin1 = cm.jet
        cmap_nonlin1 = nlcmap(cmap_lin1, levels1)
    
        subplot(4,1,1)
        contourf(x, y, H, levels, cmap=cmap_nonlin)
        colorbar()
        subplot(4,1,2)
        contourf(x, y, H, levels, cmap=cmap_lin)
        colorbar()
        subplot(4,1,3)
        contourf(x, y, H1, levels1, cmap=cmap_nonlin1)
        colorbar()
        subplot(4,1,4)
        contourf(x, y, H1, levels1, cmap=cmap_lin1)
        colorbar()
    
        plt.show()  
    

    【讨论】:

      【解决方案2】:

      levels1 = [-50, -20, -9, -6, -3, -2, -1, 0] 的示例中,当您说 self._x = self.levels/ self.levels.max() 时,您被零除。似乎pcolorcontourf 之类的函数在将输入数据传递给颜色图之前,会在 0 和 1 之间重新缩放输入数据。因此,您还需要将级别重新调整到该范围,您的代码对第一个示例执行此操作,但对第二个示例执行此操作。这似乎有效:

      class nlcmap(LinearSegmentedColormap):
          """A nonlinear colormap"""
      
          name = 'nlcmap'
      
          def __init__(self, cmap, levels):
              self.cmap = cmap
              self.monochrome = self.cmap.monochrome
              self.levels = asarray(levels, dtype='float64')
              self._x = self.levels-self.levels.min()
              self._x/= self._x.max()
              self._y = linspace(0, 1, len(self.levels))
      
          def __call__(self, xi, alpha=1.0, **kw):
              yi = interp(xi, self._x, self._y)
              return self.cmap(yi, alpha)
      

      【讨论】:

        【解决方案3】:

        与修改颜色图相比,更简单的方法是定义一种新的规范化类型以应用于您的数据,以便将其映射到 [0, 1] 范围内。

        这里我修改了this previous answer的一个例子:

        import numpy as np
        import matplotlib.pyplot as plt
        from matplotlib.colors import Normalize
        
        class PiecewiseNorm(Normalize):
            def __init__(self, levels, clip=False):
                # the input levels
                self._levels = np.sort(levels)
                # corresponding normalized values between 0 and 1
                self._normed = np.linspace(0, 1, len(levels))
                Normalize.__init__(self, None, None, clip)
        
            def __call__(self, value, clip=None):
                # linearly interpolate to get the normalized value
                return np.ma.masked_array(np.interp(value, self._levels, self._normed))
        

        例如:

        y, x = np.mgrid[0.0:3.0:100j, 0.0:5.0:100j]
        H = 50.0 * np.exp( -(x**2 + y**2) / 4.0 )
        levels = [0, 1, 2, 3, 6, 9, 20, 50]
        
        H1 = -50.0 * np.exp( -(x**2 + y**2) / 4.0 )
        levels1 = [-50, -20, -9, -6, -3, -2, -1, 0]
        
        fig, ax = plt.subplots(2, 2, gridspec_kw={'width_ratios':(20, 1), 'wspace':0.05})
        
        im0 = ax[0, 0].contourf(x, y, H, levels, cmap='jet', norm=PiecewiseNorm(levels))
        cb0 = fig.colorbar(im0, cax=ax[0, 1])
        
        im1 = ax[1, 0].contourf(x, y, H1, levels1, cmap='jet', norm=PiecewiseNorm(levels1))
        cb1 = fig.colorbar(im1, cax=ax[1, 1])
        
        plt.show()
        

        这种方法的一个优点是可以对任何颜色图使用相同的标准化。

        【讨论】:

          猜你喜欢
          • 2021-01-05
          • 2018-06-22
          • 2018-02-28
          • 2018-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-19
          • 1970-01-01
          相关资源
          最近更新 更多