如何用更强的对比度着色表面

时间:2011-02-22 04:06:03

标签: python matlab plot

在Matlab中,我试图使用以下代码在2维欧几里德空间上绘制函数

s=.05;
x=[-2:s:2+s];
y=[-1:s:3+s];
[X,Y]=meshgrid(x,y);
Z=(1.-X).^2 + 100.*(Y-X.*X).^2;
surf(X,Y,Z)
colormap jet

这是我的情节:

enter image description here

我希望用更强的对比度为表面着色,就像Wikipedia所示 enter image description here

维基百科中的情节用Python代码绘制:

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.colors import LogNorm
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = Axes3D(fig, azim = -128, elev = 43)
s = .05
X = np.arange(-2, 2.+s, s)
Y = np.arange(-1, 3.+s, s)
X, Y = np.meshgrid(X, Y)
Z = (1.-X)**2 + 100.*(Y-X*X)**2
ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, norm = LogNorm(), cmap = cm.jet)

plt.xlabel("x")
plt.ylabel("y")

plt.show()

我的Matlab代码和维基百科Python代码似乎都使用“jet”作为colormap,但它们的高度值与颜色的实际映射是不同的。所以我想知道如何在Matlab中获得类似的着色?

谢谢和问候!

2 个答案:

答案 0 :(得分:7)

您可以通过以下方式实现类似的外观:

以下是修改代码的方法:

s = .05;
x = [-2:s:2+s];
y = [-1:s:3+s];
[X, Y] = meshgrid(x, y);
Z = (1.-X).^2 + 100.*(Y-X.*X).^2;
minZ = min(Z(:));  % Find minimum value of Z
maxZ = max(Z(:));  % Find maximum value of Z
C = minZ+(maxZ-minZ).*log(1+Z-minZ)./log(1+maxZ-minZ);  % Create a log-scaled
                                                        %   set of color data
surf(X, Y, Z, C, 'EdgeColor', 'none');
colormap jet

这是由此产生的情节:

enter image description here


日志缩放的工作原理......

用于生成颜色数据Z的对数缩放C数据会导致喷射颜色映射的红橙色范围被更多表面点使用,从而提高了对比度特殊表面。通过这个简单的例子可以看到它的工作方式:

x = 0:5:100;        % Create a range of values from 0 to 100
plot(x, x, 'b-*');  % Plot the values as a straight line (y = x) in blue
hold on;            % Add to the plot
plot(x, 100.*log(1+x)./log(101), 'r-*');  % Plot a log-scaled version of x in red
colorbar            % Display the default jet color map, for comparison

enter image description here

原始蓝点均匀分布在右侧颜色条中对应的颜色范围内。对数缩放时,这些点向上移动到红线。请注意,这会导致蓝绿色范围内的点密度降低,红橙色范围内的点密度增加。


总体上获得更好的对比......

对于此处使用的特定曲面,颜色数据的对数缩放有助于在曲面上的所有点上使用更大范围的颜色贴图。由于在较低高度(即颜色指数)值处有许多点,因此对数比例扩大了这些低点以在表面的大槽中使用更宽范围的颜色。

但是,如果您想通过更好地使用颜色贴图的范围来改善任意曲面的对比度,则日志缩放并不总是有效。可能更好的一般解决方案是按升序对表面的所有高度值进行排序,然后将这些值映射到跨越整个颜色映射的线性范围。如果您为上述表面执行此操作,您将获得以下内容:

C = Z;
[~, index] = sort(C(:));
C(index) = 1:numel(index);
h = surf(X, Y, Z, C, 'EdgeColor', 'none');
colormap jet
caxis([1 numel(index)]);

enter image description here

这通常应该提供比C = Z默认表面着色更好的对比度。

答案 1 :(得分:1)

直接离开colormap的帮助页面:

  

颜色文件夹中的文件会生成许多色彩映射。每个文件都接受colormap大小作为参数。例如,

     

颜色表(HSV(128))   创建一个128色的hsv色彩映射。如果未指定大小,则会创建与当前色彩映射相同大小的色彩映射。

我已使用此功能更改颜色范围,以便更好地利用可用光谱。