具有多个比例的 Matlab 曲面图颜色图

Matlab surface plot colormap with multiple scales

我有以下跨越 [x,y] 域的示例数据集:

test=[2.58,2.2, 0.00023, 0.000163, 0.000123, 0.000164, 0.00022,   2.18, 2.56,2.56; 
 2.46,2.17, 0.00021, 0.000150, 0.000119, 0.000141, 0.00020,  2.16, 2.43, 2.56; 
 2.35,2.14, 0.00019, 0.000143, 0.000101, 0.000136, 0.00018,  2.14, 2.36,2.56; 
2.23,2.12,  0.000184, 0.000138, 0.000095, 0.000124, 0.000166, 2.12, 2.24,2.56; 
 2.2,2.11, 0.000177, 0.000141, 0.00009, 0.000101, 0.000156,  2.09, 2.18, 2.56; 
 2.25,2.1, 0.000176, 0.000168, 0.00008, 0.000095, 0.000164, 2.08, 2.26, 2.56; 
 2.32,2.13, 0.000183, 0.000178, 0.000086, 0.000104, 0.000177,  2.11, 2.35,2.56; 
2.44, 2.15, 0.00019, 0.000191, 0.000099, 0.000112, 0.000189,  2.13, 2.44,2.56; 
 2.56, 2.17,0.00021, 0.000199, 0.000101, 0.000132, 0.000199,  2.15, 2.52,2.56; 
 2.59, 2.19, 0.00022, 0.000209, 0.000118, 0.000144, 0.00021, 2.19,2.55, 2.56]

可以看到,边缘的数据比中间的数据高很多,即有两种不同的尺度。使用 Matlab 曲面图 (surf(test)) 我可以选择关注边缘,通过在 2.6 上设置颜色图最大值,我得到: Focus on the edges。 这很好地显示了边缘的局部差异,但看不到中间部分的差异。

或者,我可以通过将最大值设置为 0.00025 来关注中间,我得到: Focus on the middle, 它显示了中间的局部差异,而不是边缘的差异。 我真的很想把两者结合起来。我经常使用 colormapeditor,但还没有找到令人满意的解决方案。

理想情况下,我会将颜色条分成两个区域,一个蓝色区域范围从 00.00023(中间区域的最大值),第二个黄色区域范围从 0.000232.59(边缘区域的最大值)。 或者,可以将两张图片进行一些叠加(在 2D 中相当容易,但我也想在 3D 中这样做),但我更喜欢使用自定义颜色条来解决它。

有人知道怎么做吗?

您可以改为绘制数据日志,例如

surf(log(test))
caxis(log([min(test(:)) max(test(:))]));
colorbar_array = linspace(log(min(test(:))), log(max(test(:))), 5);
colorbar('FontSize',11,'YTick',colorbar_array,'YTickLabel',exp(colorbar_array));

编辑:您仍然需要 fiddle 使用颜色图编辑器,以解决数据范围上限的差异(黄色区域)。

您遇到的问题是高动态范围数据。这个一般没办法解决。

从高动态范围(HDR)摄影的角度来看,你要做的事情有一个名字:Tonemapping。关于如何解决这个问题没有简单的答案。按照 Amos 的建议对数据取对数,这是很好的第一步。这通常在查看高动态范围的信号频谱(例如图像的功率谱)时完成,由于功率谱和自然图像之间的统计联系,它更普遍地起作用。

第二种方法(很简单)是对图像应用 gamma-correction。这为您提供了一个可以调整的简单参数,对于一些二维数据就足够了。

正如您自己指出的那样,对数(或伽玛校正)通常不会根据需要重新缩放数据。这是色调映射仍然是一个开放研究领域的原因之一。

话虽如此,有全自动的方法,有一些是在 Matlab 中实现的。这是 I have never tried myself, but supported by mathworks.