如何生成非线性的颜色映射/颜色条?

5

我想展示一个非均匀的色条,就像第一张图片中展示的那样。我已经尝试了下面的代码。'mycamp4' 是一个手动保存的颜色映射表。结果如第二张图片所示。数字0.11.5太接近了,无法分辨。我该如何使色条看起来像第一张图片?

v = [0.1 1 1.5 5 7.5 10 30];
v_2 = [0.1 1.5 5 7.5 10 30];
contourf(X,Y,pdf_normal',v);
h = colorbar;
load('MyColormaps','mycmap4');
set(gcf,'Colormap',mycmap4);
set(h, 'YTick', v_2)

图片1:

在这里输入图片描述

图片2:

在这里输入图片描述


也许这可以帮助:对数色条 - Robert Seifert
你的意思是想要一个非均匀的色图吗?colorbar通常只显示colormap的内容。我猜你已经尝试过colormapeditor了。你应该在文件交换平台上搜索自定义色图。 - horchler
附注:第一张图片中的条形图似乎具有超过30的值,而您的第二个色条仅显示值直到30。 - Dennis Jaheruddin
@DennisJaheruddin 我认为它们没有关联。只是例子。 - Robert Seifert
4个回答

10

以下是逐步说明。

首先请看以下示例:

[X,Y,Z1] = peaks;

figure(1)
[~,h1] = contourf(X,Y,Z1,20);
a1 = colorbar;
colormap(jet)
caxis([-6,6])

将会给你以下绘图结果:

enter image description here

该图具有线性数据和线性颜色映射。现在我想要将Z数据缩放,使其像您的情况一样变为非线性。我选择了简单的对数据进行平方操作。

Z2 = get(h1,'ZData');
scalefactor = @(x) sign(x).*x.^2;
Z2 = scalefactor(Z2);

这是实际的示例数据,与您的类似:

figure(2)
[~,h2] = contourf(X,Y,Z2,20);
a2 = colorbar;
colormap(jet)
caxis([-6^2,6^2])

这里输入图片描述

我们现在有非线性数据,但仍然使用线性的colormapcolorbar

到目前为止,一切都是为了生成类似于您的示例数据。


现在是真正的答案:

获取绘图的数据:

Z3 = get(h2,'ZData');

并使用您希望更多或更少了解的关系来扩展它:

descalefactor = @(x) sign(x).*abs(x).^(1/2);
Z3 = descalefactor(Z3);

绘制已缩放数据的图表:

figure(3)
[~,h3] = contourf(X,Y,Z3,20);
a3 = colorbar;
colormap(jet)
caxis([-6,6])

获取 Y 轴刻度值 并使用其反函数进行缩放,就像您的数据一样:

ticks = get(a3,'YTick');
ticks = scalefactor(ticks);

设置这些反比例缩放的颜色条刻度。
set(a3,'YTickLabel',ticks)

现在,你最终得到了一条看似线性的图表(但你可以备份之前的非线性数据),并且还有一个非线性的颜色映射和颜色条刻度。

enter image description here

正如预期的那样,这个图表看起来和第一个例子中的一样,只是颜色条轴被缩放了。

如果你没有任何函数关系,请尝试获取一个,例如使用曲线拟合工具箱。


嗨@thewaywewalk,非常感谢!!看起来有效。我会试一下! - user2230101
快速提示:我发现如果您更改窗口的大小,使得色条上的刻度数发生变化,它们将不再正确匹配色条(实际上,如果添加了新的刻度,它们将重复)。在调整图形大小后,您必须重新调整色条的比例。 - Mark H
@MarkH 这是真的,这就是为什么你应该创建正确大小的图形。 - Robert Seifert

1
你可以自定义色图和颜色条的刻度,但颜色条本身是基于线性间隔的,并且您无法更改它。
但是,有一个解决方法。
假设您想要将颜色条设置为像图片1中那样具有N个非线性间隔(例如,如果N=2,则color_limits=[1 2 20]),则需要执行以下操作:
1)为您的数据定义另一个变量,例如:
data2 = nan(size(data));
for i=1:N
   b = data>color_limits(i) & data>=color_limits(i+1);
   data2(b) = i-0.5;
end

基本上,您正在将数据分bin,并使用color_limits中的间隔到不同的变量data2中进行显示。
2)创建data2的图像。
3)定义colorbar的限制:caxis([0 N])
4)定义具有N种颜色的colormap,例如colormap(jet(N))
5)自定义colorbar中的刻度。

0

可以尝试使用 Recolor_contourf。它有两个更多的函数,易于使用。 在其帮助中,给出了以下示例。该函数由我提交。如果遇到任何问题,请告诉我。

X=1:10;Y=1:10;
C=rand(10,10)*150;
c=colormap(jet(7));
L=[10 20 50 60 70 100];
[cdd hc]=contourf(X,Y,C,[-5 L]);
Recolor_contourf(hc,c,L,'vert');

0

当你尝试使用doc colorbar时,你会找到一个关于颜色映射的参考。在尝试了doc colormap之后,他们基本上给出了三个选项来设置颜色映射。

  1. 输入一个映射(例如通过get获得的映射或之前设计的映射,这就是你尝试的内容)
  2. 使用属性编辑器选择内置的颜色映射。
  3. 使用颜色映射编辑器,可从图形菜单上的“编辑”>“颜色映射”中访问。

@horchler已经提到过了,但我认为你之前没有听说过颜色映射编辑器。因此,我认为选项3最适合你。


亲爱的Dennis,非常感谢您的回复。实际上我已经尝试过色图编辑器(我的原始代码中使用了“mycmap4”)。但是它并没有改变颜色条的比例尺。例如,我希望0.1到1之间的距离与1到2.5之间的距离相同。我认为@thewaywewalk提到的对数刻度颜色条接近我想要的结果。但是我需要的不是对数刻度而是“定制”的刻度。 - user2230101
我所能想到的唯一方法是完全线性化你打算使用的关系数据,然后使用自定义刻度标签。 - Robert Seifert

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