在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

这是我的情节的样子:

我希望像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.*(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代码和Wikipedia Python代码似乎都使用“jet”作为颜色图,但是它们实际的高度值到颜色的映射是不同的。所以我想知道如何在Matlab中获得类似的颜色?

感谢致敬!

最佳答案

您可以通过以下方式获得类似的外观:

  • 将表面对象的 'EdgeColor' property设置为'none'以消除边缘着色。
  • 修改表面的 'CData' property以模仿Python代码中的log-scaling of the color data

  • 这是修改代码的方法:
    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
    
    这是结果图:

    日志扩展的工作方式...
    对数缩放的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
    

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

    总体上获得更好的对比...
    对于此处使用的特定表面,颜色数据的对数缩放有助于在表面上的所有点上使用更大范围的颜色图。由于在较低高度(即颜色索引)值上有许多点,因此对数缩放将这些低点分布得更多,以便在表面的大槽中使用更广泛的颜色。
    但是,如果您想通过更好地利用颜色图的范围来改善任意表面的对比度,对数缩放将永远不会起作用。可能会更好的一种通用解决方案是按升序对曲面的所有高度值进行排序,然后将它们映射到跨越整个颜色图的线性范围。如果您在上面进行此操作,将会得到以下结果:
    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默认表面着色更好的对比度。

    关于python - 如何用更强的对比度为表面着色,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5073865/

    10-12 17:45