【问题标题】:Logarithmic colormap in matplotlibmatplotlib 中的对数颜色图
【发布时间】:2014-12-02 22:32:18
【问题描述】:

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

背景: 在 matplotlib 中通过imshow(...) 命令绘制数组时,colormaps 用于为每个数据值分配颜色。通常,预定义的颜色图从matplotlib.cm 使用,但也可以使用matplotlib.colors.LinearSegmentedColormap 创建更多增强的颜色图。 通常,在这些颜色图中,颜色值会随着数据值线性变化。

提示:我的问题是不是,如何以对数方式绘制数组。这通常是通过保留线性颜色图和一些技巧来完成的(通过绘制log(array) 并将颜色条上的标签x 替换为10^x,或者通过显式更改绘图命令的规范化行为)。在这里,我明确需要颜色图实例。

【问题讨论】:

  • 所以imshow(data,norm=matplotlib.colors.LogNorm()) 不是您要找的东西?这基本上就是您在提示中描述的内容。是不是要以对数方式绘制数组,但要以线性方式绘制颜色条?
  • @burnpanck 不,这正是我想要的,我需要一个以对数方式工作的自治颜色图实例。原因是我使用了一个不同的软件,它使用 matplotlib 颜色图生成绘图。
  • 好的,什么样的软件,你是通过什么方式把colormap传给它的?原因是,可以很容易地编写一个自定义的Colormap 子类,它只包装另一个颜色图,应用线性到对数的转换。不过,这样的自定义类能不能通过还不清楚。
  • @burnpanck 嗯,它是我们研究组的私人绘图库。我认为您的建议可以解决我的问题,因为绘图软件只是将颜色图应用于计算颜色,因此不应该关心它是 LinearSegementedColormap 还是派生自 Colormap 的任何其他实例。

标签: python numpy matplotlib colors


【解决方案1】:

您可以提供一个伪造的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)。如果要将颜色图应用于非标准化值,请将其留空:

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
))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    相关资源
    最近更新 更多