【问题标题】:Automatic construction of a colormap around the value zero围绕零值自动构建颜色图
【发布时间】:2013-05-27 22:19:22
【问题描述】:

我经常想绘制一张从某个负数到某个正数的差异图像。问题在于matlab的颜色图仅从最小值缩放到最大值,但不关心一些中间值(本例为零)。例如,我制作了具有单个像素不同的peaks 图像:

原来的样子是这样的:

所以零值在顶部图像为蓝色,在底部为绿色...(以 jet colormap 为例)

我想构建一个颜色图,无论最小\最大值是什么,它都会自动将零值表示为相同的颜色。我该怎么做?

【问题讨论】:

  • 我认为您可以通过在绘图之前将所有内容缩放到固定间隔来实现这一点,例如[-1,1]
  • 使用颜色映射编辑器:mathworks.de/de/help/matlab/ref/colormapeditor.html 解释了如何将绿色聚焦为零
  • Robocob 特别要求自动实现,这样他就不需要每次都打开颜色图编辑器...
  • 您可以使用caxis 通过使用以零为中心的范围来控制颜色映射,这样0 始终位于中间(假设您使用的是缩放颜色映射而不是直接映射)

标签: matlab plot color-mapping


【解决方案1】:

可以使用caxis 函数(设置当前坐标区对象的CLim 属性)来控制颜色映射。当然,假设是使用缩放颜色映射,而不是直接颜色映射(阅读CDataMapping 属性)。通过使用以零为中心的范围作为输入,您可以确保零始终位于中间。

这是一个例子:

load penny
P = 4*(P./255) - 1;        %# not centered around zero
imagesc(P), axis image off
colormap(lbmap(64,'BrownBlue')), colorbar

现在我们调整颜色映射使其围绕零对称:

c = max(abs([min(P(:)),max(P(:))]));
caxis([-c c])

请注意,我使用的是Light Bartlein color scheme,它被设计为一个发散的调色板,以突出两个极端之间的差异。

如果原始范围非常偏斜,您可能需要重新采样颜色图以在过度拉伸的子范围内为其提供更多值。

【讨论】:

  • 感谢 Amro,但如果我理解正确,假设我需要将我的颜色图以零为中心,在大多数情况下,下限和上限不是围绕零对称的。所以处理它的方法是设置限制,无论哪个绝对值更大,我猜。
  • 是的,我认为这适用于您...毕竟有很多应用程序的零值很重要(例如显示海平面为零的地形图)。最简单的方法是使用以零为中心的颜色范围和适当的对称颜色图,然后让 MATLAB 进行缩放。另一种方法是分段构建,每个部分都是两个端点之间的线性映射,这样您就可以拥有任意数量的“节点”(类似于上面提到的colormapeditor
  • c = max(abs((P(:))); 就够了
【解决方案2】:

您可以使用来自 FEX 的this tool。它生成蓝白红颜色图,零总是对应于白色。对于您想要包含两种以上颜色的情况,请深入了解code 并根据您的需要进行调整。

FEX 中还有更多选项可以做类似的事情(这里是 oneanother one)...

【讨论】:

    【解决方案3】:

    我喜欢其他答案,尤其是@Amro 的答案。但它看起来很复杂 :) 你的caxis 参数不需要依赖于你的输入,你可以简单地从轴上抓取它们。所有这些都可以是一条线:

    a = gca; % or whatever you use to access your axis handle
    a.CLim = max(abs(a.CLim)) * [-1 1];
    

    就是这样。这适用于具有新图形处理系统的 MATLAB R2014b 及更高版本(请参阅更多详细信息 here)。在早期版本(以及新版本,如果您愿意)中,您可以使用

    a = gca; % or whatever you use to access your axis handle
    set(a, 'CLim', max(abs(get(a, 'CLim'))) * [-1 1]);
    

    或者,使用caxis

    a = gca; % or whatever you use to access your axis handle
    caxis(a, max(abs(caxis(a))) * [-1 1]);
    

    自动化也相当容易:

    a = gca; % or whatever you use to access your axis handle
    addlistener(a, 'CLimMode', 'PostSet', @(h, e) caxis(e.AffectedObject, max(abs(caxis(e.AffectedObject))) * [-1 1]));
    

    这允许你这样做

    for ii = -5 : 5
        imagesc([-1 0 10^ii]);
        pause(0.2);
    end
    

    并且中间的条纹(代表 0)始终是颜色条的中间颜色。

    【讨论】:

    • 感谢addlistener。不知道这存在,但它似乎非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2021-12-26
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 2018-05-07
    • 2021-11-02
    相关资源
    最近更新 更多