如何在Matlab中将颜色明确地与热图中的值相关联?

5

我有一个由整数(1、2或3)构成的矩阵M。我想用热力图来表示它,并将颜色分别固定为1、2和3。我使用了以下代码:

map = [1, 1, 0;  % color for 1 (yellow)
       1, 0.5, 0 ; % color for 2 (orange)
       0, 1, 0.5]; % color for 3 (green)

HeatMap(M,'Colormap',map,'Symmetric','false'); 

当 M 中至少包含一个 1、一个 2 和一个 3 时,没有任何问题。但是当 M 只包含 3 时,热力图并不符合我的要求(全是绿色)。 如何解决这个问题?


1
你需要热力图吗?使用其他函数,如imshow也可以得到类似的结果。 - Ander Biguri
1
我不知道这个函数,谢谢。我正在尝试使用它,但目前还没有令人满意的结果... - JuliaR
1
Kovesi也制作了一些漂亮的感知均匀的色图,可能对你有所帮助。 - Maurits
1
@Maurits 非常有趣!我认为在较新的Matlab版本中,这些问题已经得到了解决,例如parula配色方案。 - Ander Biguri
你最终都拒绝了这两个答案 - 为什么? - Robert Seifert
2个回答

3

看起来你不能轻易地做到这一点。 在Matlab 2013b或更早版本(我没有在2014b中尝试过),当你调用HeatMap时,它会内部经历一个创建坐标轴、设置颜色等过程。最终它会到达plot.m中的一个点,调用以下函数:

function scaleHeatMap(hHMAxes, obj)
%SCALEHEATMAP Update the CLIM in image axes
if obj.Symmetric
    maxval = min(max(abs(obj.Data(:))), obj.DisplayRange);
    minval = -maxval;
else
    maxval = min(max(obj.Data(:)), obj.DisplayRange);
    minval = min(obj.Data(:));
end
set(hHMAxes, 'Clim', [minval,maxval]);
end

这个函数实际上是使用热图的轴(hHMAxes)来定义颜色映射的限制,但不幸的是,该对象并没有被HeatMap()调用返回。

我能想到的唯一解决办法是:

  1. 修改plot.m函数。这通常是一个非常糟糕的想法。
  2. 创建一个myHeatMap函数,它做了原始函数所做的一切,但在轴的Clim属性上改变了功能。
  3. 根本不使用HeatMap,而是使用例如surfimshow创建一个看起来相同的图。
  4. 在调用HeatMap之前执行一个if语句,并检查颜色映射中是否有单个值(numel(unique(M(:)))==1),如果发生这种情况,请将map更改为具有您选择的颜色的单值颜色映射。

最简单的方法是第四种。


2
非常感谢您提供这么精确的回复 :) - JuliaR
1
@JuliaR 不用担心!如果答案有用,请记得接受它! - Ander Biguri

3
最简单的方法是不使用HeatMap,这是一个基于Java的相当不便的函数。
相反,使用 imagescpcolor,在这里您可以轻松地使用caxis来修复颜色轴。
map = [1, 1, 0;  % color for 1 (yellow)
       1, 0.5, 0 ; % color for 2 (orange)
       0, 1, 0.5]; % color for 3 (green)


%// left plot
subplot(131)
M = randi(3,3,3); 
imagesc(M)
colormap(map)
caxis( [1 3] )

%// right plot
subplot(132)
M = 3*ones(3); 
imagesc(M)
colormap(map)
caxis( [1 3] )

%// legend
subplot(133)
set(gca,'visible','off')
c = colorbar
caxis( [1 3] )
c.Ticks = [1.25,2,2.75]
c.TickLabels = 1:3

enter image description here


确实是个很棒的答案。 - Ander Biguri

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