Как покрасить поверхность с более сильным контрастом - PullRequest
6 голосов
/ 22 февраля 2011

В 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

Я надеюсь покрасить поверхность с более сильным контрастом, как показывает Википедия 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" в качестве карты цветов, но их фактическое отображение значения высоты в цвет отличается. Поэтому мне было интересно, как я могу получить подобную раскраску в Matlab?

Спасибо и всего наилучшего!

Ответы [ 2 ]

7 голосов
/ 22 февраля 2011

Подобный внешний вид можно получить с помощью:

Вот как вы можете это сделатьизмените ваш код:

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 голос
/ 22 февраля 2011

Прямо из страницы справки для карты цветов:

Файлы в папке цветов генерируют несколько цветовых карт. Каждый файл принимает размер карты цветов в качестве аргумента. Например,

Colormap (ВПГ (128)) создает цветовую карту hsv со 128 цветами. Если вы не укажете размер, будет создана цветовая карта того же размера, что и текущая цветовая карта.

Я использовал эту функцию для изменения диапазона цветов, чтобы лучше использовать доступный спектр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...