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

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

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

cmap1=colormap(topobathy) --> cmap1 имеет двойной размер 64x3, как и ожидалось.

cmap2=colormap(redwhitegreen)

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

b=surf(x,y,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)`

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

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

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

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


person theenemy    schedule 09.11.2011    source источник


Ответы (3)


Основная идея заключается в том, что вы объединяете карты цветов, а затем сдвигаете/масштабируете данные цвета (CData) различных маркеров графика, чтобы они соответствовали нужным частям карты цветов. Таким образом, не зная ваших пользовательских функций или конкретных данных, вы можете сделать что-то вроде colormap(topobathy(64); redwhitegreen(64)), а затем масштабировать CData из b в диапазоне [1,64] и CData из 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)

введите здесь описание изображения

person John Colby    schedule 10.11.2011
comment
спасибо за ответ - это хорошая ссылка, я знал об этом, но это не относится к моей проблеме - мой серфинг и pcolor используют разные наборы данных Z. Я хочу, чтобы их соответствующая цветовая панель и цветовая карта отражали это. - person theenemy; 10.11.2011
comment
Нет никаких требований, чтобы они были одинаковыми значениями Z, и я призываю вас внимательно изучить этот пример. Суть в том, что каждый CData должен масштабироваться/смещаться в соответствующую часть объединенной карты цветов. Даже карты цветов не обязательно должны быть 64-64, хотя мне всегда удобнее иметь их одного размера. - person John Colby; 10.11.2011
comment
@theenemy Кроме того, если вам действительно нужны 2 цветные полосы, это тоже просто. Просто создайте 2 из них, а затем настройте свойство Position, чтобы они не перекрывались, и свойство YLim, чтобы каждое отображало только одну часть карты цветов. - person John Colby; 10.11.2011

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

  1. #P2# <блочная цитата> #P3# #P4#
  2. #P5#
    #P6#
    #P7#
    data2 = data2 - lower_limit;
    data2 = double(data2./(upper_limit2 - lower_limit2)) + 1;
    
  3. При их представлении:

    • 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);
    
    • Оси2:
    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, в зависимости от ваших потребностей. Надеюсь, поможет!

person YisasL    schedule 23.07.2014

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

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

Расчет пределов цвета

Ключом к этому примеру является вычисление значений для 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 слота. Вам также необходимо сбросить его значения 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.

person yellowjacket05    schedule 20.02.2015