Matlab: как назначить разные цветовые карты/цветные панели на разные поверхности на том же рисунке

Я новичок в Matlab и задаю несколько вопросов. У меня две поверхности и плоскость на том же рисунке. Я хочу использовать разные цветовые карты и colorbar для b и еще один colormap и colorbar для c. s является фиксированным цветом, поэтому это не проблема.

Позвольте мне попытаться объяснить, чего я пытаюсь достичь:

cmap1 = colormap (topobathy) → cmap1 равен 64x3, как ожидается,

cmap2 = Colormap (redwhitegreen)

создать cdata1 с помощью cmap1 (это первая часть, которую я не могу понять, как масштабировать данные z с помощью cmap1, по умолчанию CData содержит значения z)

Ь = прибой (х, у, г, cdata1)

colorbar для b с использованием значений z

c = pcolor (x, y, (z-z0)) - Я хочу использовать cmap2 для этого.

colorbar для c с использованием значений (z-z0)

Вот что я до сих пор и проблемы, с которыми я сталкиваюсь

b=surf(x,y,z);
colormap(topobathy);
cbar1=colorbar;
set(get(cbar1,'ylabel'),'String', 'Elevation (m)', 'Rotation', 90)
hold on;
s=surf(x,y,z1,'FaceColor',[0.278 0.788 0.788])
hold on;
change=z-z0;     
c=pcolor(x,y,change)
set(c,'ZData',100 + 0*change); %plotting it above the other surfaces
colormap(redwhitegreen)`

в этот момент для colormap установлено значение redwhitegreen для b, colorbar of b Я не могу получить второй цветной план с собственным кликом и т.д.

Я использовал freezeColors и cbfreeze в этой ссылке: http://blogs.mathworks.com/pick/2009/07/24/using-multiple-colormaps-in-a-single-figure/

но одна вещь работает, когда возится другая вещь (возможно, вся моя вина). Я хочу узнать, как получить полный контроль над моими объектами, не используя внешние файлы m в любом случае.

Любая помощь приветствуется.

Ответ 1

Основная идея состоит в том, что вы объединяете цветовые палитры, а затем меняете/масштабируете цветные данные (CData) разных дескрипторов сюжета, чтобы выстроить их в соответствие с нужными частями цветовой карты. Итак, не зная, какие ваши пользовательские функции или конкретные данные, вы можете сделать что-то вроде colormap(topobathy(64); redwhitegreen(64)), а затем масштабировать CData of b в диапазоне [1,64] и CData of c в диапазон [65, 128].

На веб-сайте MathWorks есть отличное руководство, которое объясняет все это (даже использует surf() и pcolor() как ваш пример):

http://www.mathworks.com/support/tech-notes/1200/1215.html#Example_1

Для цветной панели вы можете просто подделывать метки и метки аналогичным образом. Вот грубый снимок при создании цветной полосы для приведенного выше примера:

h = colorbar;
ticks = [1 16:16:64 64:16:128];
ticks(5:6) = [62 66];
set(h, 'YTick', ticks);

labels = num2str(repmat(linspace(min(Z(:)), max(Z(:)), 5), 1, 2)', 2);
set(h, 'YTickLabel', labels)

enter image description here

Ответ 2

У меня была та же проблема, что и вы, и лучшее (и единственное) решение, которое я нашел, было следующим:

  • Объединить оба цветовых пакета, которые я хотел:

    cmap1 = jet (64); cmap2 = медь (64); color_map = [cmap1; cmap2];

    Итак, для осей 1 будет использоваться первая цветовая палитра (cmap1), а вторая цветовая палитра (cmap2) для Axes2. Я думаю, что Axes1 и Axes2 находятся на одном рисунке.

  • Нормализовать данные, давая масштаб от 0 до 1 для данных Axes1 и от 1 до 2 для данных Axes2. Итак, оси 1 в [0, 1] и оси 2 в [1 2].

    data1 = data1 - lower_limit1;     data1 = double (data1./(upper_limit1 - lower_limit1));

    Для набора данных осей 2:

    data2 = data2 - lower_limit;
    data2 = double(data2./(upper_limit2 - lower_limit2)) + 1;
    
  • При представлении их:

    • Axes1:
    pcolor(handle_axes1, x_axis, y_axis, data1); shading(handle_axes1,'FLAT'); 
    caxis(handle_axes1, [0 2]);
    
    % Colorbar
    h_colorbar = colorbar('peer', handle_axes1);
    set(h_colorbar, 'YLim', [0 1]);
    
    labels = num2str(linspace(lower_limit1, upper_limit1, 6)', 2);
    set(h_colorbar, 'YTick', linspace(0, 1, 6));
    set(h_colorbar, 'YTickLabel', labels);
    
    • Axes2:
    pcolor(handle_axes2, x_axis, y_axis, data2); shading(handle_axes2,'FLAT'); 
    caxis(handle_axes2, [0 2]);
    
    % Colorbar
    h_colorbar2 = colorbar('peer', handle_axes2);
    set(h_colorbar2, 'YLim', [1 2]);
    
    labels = num2str(linspace(lower_limit2, upper_limit2, 6)', 2);
    set(h_colorbar2, 'YTick', linspace(1, 2, 6));
    set(h_colorbar2, 'YTickLabel', labels);
    

Используйте pcolor или surf, в зависимости от ваших потребностей. Надеюсь, это поможет!

Ответ 3

Matlab предоставил код для функции newclim, который решает эту проблему чисто, объединяя цветовые карты в один цветовой пакет. Я мог найти эту документацию только в справке 2012b, но не в Интернете.

Обратите внимание, что осями, используемыми для обновления CLim в качестве последнего шага, могут быть оси для графиков surf, как я применяю этот код.

Вычисление цветовых ограничений

Ключ к этому примеру - вычисление значений для CLim, которые заставляют каждую поверхность использовать раздел цветовой карты, содержащий соответствующие цвета.

Чтобы вычислить новые значения для CLim, вам необходимо знать

  • Общая длина цветовой карты (CmLength)

  • Начальный слот цветовой карты для использования для каждой оси (BeginSlot)

  • Конечный слот цветовой карты для использования для каждой оси (EndSlot)

  • Минимальные и максимальные значения CData графических объектов, содержащихся в осях. То есть значения свойств осей CLIM определены по MATLAB, когда CLimMode является авто (CDmin и CDmax).

Сначала определите области подзадачи и постройте поверхности.

im1 = load('cape.mat');
im2 = load('flujet.mat');
ax1 = subplot(1,2,1); 
imagesc(im1.X) 
axis(ax1,'image')
ax2 = subplot(1,2,2);
imagesc(im2.X) 
axis(ax2,'image')

Совместите две цветовые карты и установите новую цветочную карту.

colormap([im1.map;im2.map])

Получите данные, необходимые для вычисления новых значений для CLim.

CmLength   = length(colormap);   % Colormap length
BeginSlot1 = 1;                  % Beginning slot
EndSlot1   = length(im1.map);    % Ending slot
BeginSlot2 = EndSlot1 + 1; 
EndSlot2   = CmLength;
CLim1      = get(ax1,'CLim');  % CLim values for each axis
CLim2      = get(ax2,'CLim');

Определение функции для вычисления значений CLim

Вычисление новых значений для CLim включает в себя определение части цветовой карты, которую вы хотите, чтобы каждая ось использовалась относительно общего размера цветовой карты и масштабирования ее диапазона Clim соответственно. Вы можете определить функцию MATLAB для этого.

function CLim = newclim(BeginSlot,EndSlot,CDmin,CDmax,CmLength)
   %                Convert slot number and range
   %                to percent of colormap
   PBeginSlot    = (BeginSlot - 1) / (CmLength - 1);
   PEndSlot      = (EndSlot - 1) / (CmLength - 1);
   PCmRange      = PEndSlot - PBeginSlot;
   %                Determine range and min and max 
   %                of new CLim values
   DataRange     = CDmax - CDmin;
   ClimRange     = DataRange / PCmRange;
   NewCmin       = CDmin - (PBeginSlot * ClimRange);
   NewCmax       = CDmax + (1 - PEndSlot) * ClimRange;
   CLim          = [NewCmin,NewCmax];
end

Входные аргументы указаны в маркированном списке выше. Функция сначала вычисляет процент общей цветовой карты, которую вы хотите использовать для определенных осей (PCmRange), а затем вычисляет диапазон CLim, необходимый для использования этой части цветовой карты, заданной диапазоном CData в осях. Наконец, он определяет минимальные и максимальные значения, необходимые для вычисленного диапазона CLIM, и возвращает эти значения. Эти значения являются пределами цвета для заданных осей.

Использование функции

Используйте функцию newclim для установки значений CLIM для каждой оси. Утверждение

set(ax1,'CLim',newclim(BeginSlot1,EndSlot1,CLim1(1),...
        CLim1(2),CmLength))

устанавливает значения CLim для первых осей, так что поверхность использует цветовые слоты с 65 по 120. В освещенной поверхности используются более низкие 64 слота. Вам нужно reset его значения CLim.

set(ax2,'CLim',newclim(BeginSlot2,EndSlot2,CLim2(1),...
        CLim2(2),CmLength))

Как работает функция

MATLAB позволяет указать любые значения для свойства CLIM осей, даже если эти значения не соответствуют CData графических объектов, отображаемых в осях. Минимальное значение CLIM всегда сопоставляется с первым цветом в цветовой палитре, и максимальное значение CLim всегда сопоставляется с последним цветом в цветовой палитре, независимо от того, действительно ли имеются значения CData, соответствующие этим цветам. Поэтому, если вы укажете значения для CLim, которые выходят за пределы фактического CData, минимального или максимального, MATLAB окрашивает объект только подмножеством цветовой карты.

Функция newclim вычисляет значения для CLim, которые сопоставляют фактические значения CData графического объекта с начальными и конечными слотами цветовой палитры, которые вы указываете. Он делает это, определяя "виртуальный" графический объект, имеющий вычисленные значения CLIM.