在Matlab中,我尝试使用以下代码在2维欧几里得空间上绘制函数
s=.05; x=[-2:s:2+s]; y=[-1:s:3+s]; [X,Y]=meshgrid(x,y); Z=(1.-X).^2 + 100.*(YX.*X).^2; surf(X,Y,Z) colormap jet 这是我的情节的样子:
我希望像
Wikipedia所示的那样以更强的对比度为表面着色
Wikipedia中的图是使用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.*(YX*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代码和Wikipedia Python代码似乎都使用“ jet”作为颜色图,但是它们的高度值到颜色的实际映射是不同的。所以我想知道如何在Matlab中获得类似的颜色?
谢谢并恭祝安康!
回答:
您可以通过以下方式获得类似的外观:
这是修改代码的方法:
s = .05; x = [-2:s:2+s]; y = [-1:s:3+s]; [X, Y] = meshgrid(x, y); Z = (1.-X).^2 + 100.*(YX.*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 这是结果图:
日志扩展的工作方式...
用于产生颜色数据C对数缩放Z数据使射流颜色图的红橙色范围被更多的表面点使用,从而改善了该特定表面的对比度。通过以下简单示例可以直观地了解其工作方式:
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
原始的蓝点在右侧颜色栏中对应的颜色范围内均匀分布。对数缩放后,这些点将向上移动到红线。请注意,这如何导致较低的蓝绿色范围内的点密度降低和红色橙色范围内的点密度增大。
总体上获得更好的对比...
对于此处使用的特定表面,颜色数据的对数缩放有助于在表面上的所有点上使用更大范围的颜色图。由于在较低高度(即颜色索引)值上有许多点,因此对数缩放将这些低点分布得更多,以便在较大的表面槽中使用更广泛的颜色。
但是,如果您想通过更好地利用颜色图的范围来改善任意表面的对比度,对数缩放将永远不会起作用。可能更好用的一般解决方案是按升序对曲面的所有高度值进行排序,然后将它们映射到跨整个颜色图的线性范围。如果在上面进行此操作,将会得到以下结果:
C = Z; [~, index] = sort(C(:)); C(index) = 1:numel(index); h = surf(X, Y, Z, C, 'EdgeColor', 'none'); colormap jet caxis([1 numel(index)]);
通常,这应比C = Z默认表面着色提供更好的对比度。
更多&回答...