matplotlib中的对数色图

3

是否可以定义一个matplitlib colormap,该colormap在两个给定颜色之间进行对数插值?

背景: 在matplotlib中通过imshow(...)命令绘制数组时,使用colormaps将颜色分配给每个数据值。通常情况下,从matplotlib.cm使用预定义的colormaps,也可以使用matplotlib.colors.LinearSegmentedColormap创建更加高级的colormaps。 通常,在这些colormaps中,颜色值随着数据值的线性变化而变化。

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


那么 imshow(data,norm=matplotlib.colors.LogNorm()) 不是你要找的吗?它基本上就是你在提示中描述的内容。难道你想对数组进行对数绘图,但是希望颜色条线性绘制吗? - burnpanck
@burnpanck 不,那不是我想要的,我需要一个自主的色图实例,使用对数方式工作。原因是我使用另一种软件,该软件使用matplotlib色图制作图形。 - flonk
好的,你要用什么类型的软件,以何种方式将色彩地图传递给它?原因是,人们可以很容易地编写一个自定义的'Colormap'子类,只需包装另一个颜色映射,应用线性到对数转换即可。然而,现在不清楚这样的自定义类是否可以被传递。 - burnpanck
@burnpanck 嗯,这是我们研究小组的私有绘图库。我认为您的建议可以解决我的问题,因为绘图软件只是应用颜色映射来计算颜色,因此不应关心它是LinearSegementedColormap还是从Colormap派生的任何其他实例。 - flonk
1个回答

2
你可以提供一个虚假的Colormap,它应用你所需的标准化,然后将其传递给真正的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)。如果要将色图应用于未归一化的值,请将其留空:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接