Matlab:如何在同一图中为不同的表面指定不同的色图/色块

时间:2011-11-09 23:19:05

标签: matlab matlab-figure color-mapping

我是Matlab的新手并且有一些问题。 我在同一个图中有两个表面和一个平面。 我想为b使用不同的colormap和colorbar,为c使用另一个colormap和colorbar。 s是固定颜色,所以这不是问题。

让我试着解释一下我想要实现的目标:

cmap1 = colormap(topobathy) - > cmap1按预期加倍64x3

cmap2 =颜色表(redwhitegreen)

使用cmap1创建cdata1(这是我无法弄清楚的第一部分,如何使用cmap1缩放z数据,默认情况下CData包含z值)

B =冲浪(X,Y,Z,cdata1)

b使用z值

colorbar

c = pcolor(x,y,(z-z0)) - 我想将cmap2用于此。

使用(z-z0)值

的c的

colorbar

这是我到目前为止所遇到的问题

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为b 我无法通过自己的爬升等获得第二个颜色条。

我使用了此链接中解释的freezeColors和cbfreeze: http://blogs.mathworks.com/pick/2009/07/24/using-multiple-colormaps-in-a-single-figure/

但有一件事在弄乱另一件事情时(可能是我的错)。我想学习如何在不使用外部m文件的情况下完全控制我的对象。

感谢任何帮助。

3 个答案:

答案 0 :(得分:16)

基本思想是连接颜色贴图,然后移动/缩放不同绘图控制柄的颜色数据(CData),以与颜色贴图的所需部分对齐。因此,在不知道您的自定义函数或特定数据的情况下,您可以执行colormap(topobathy(64); redwhitegreen(64))之类的操作,然后将CData的{​​{1}}缩放到范围[1,64]和{{} 1 {} b进入范围[65,128]。

MathWorks网站上有一个优秀的指南,解释了所有这些(甚至使用CDatac就像你的例子一样):

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

对于彩条,您可以用类似的方式伪造刻度线和标签。以下是为上述示例制作颜色条的粗略注意事项:

surf()

enter image description here

答案 1 :(得分:1)

我遇到了和你一样的问题,我找到的最好的(也是唯一的)解决方案就是下一个:

  1. 连接我想要的两个色图:

      

    cmap1 = jet(64); cmap2 =铜(64); color_map = [cmap1; cmap2];

    因此,第一个色图(cmap1)将用于Axes1,第二个色图(cmap2)将用于Axes2。我猜Axes1和Axes2在同一个图中。

  2. 标准化数据,对Axes1的数据给出0到1的比例,对Axes2的数据给出从1到2的比例。因此,[0,1]中的Axes1和[1 2]中的Axes2。

      

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

    对于Axes 2的数据集:

    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);
    
    • 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);
    
  4. 根据您的需要使用pcolor或surf。 希望它有所帮助!

答案 2 :(得分:1)

Matlab为函数newclim提供了代码,它通过将颜色映射连接到一个颜色映射中来干净地解决了这个问题。我只能在2012b帮助中找到此文档,但不能在线。

请注意,用于更新CLim作为最后一步的轴可能是冲浪图的轴,这就是我应用此代码的方式。

计算颜色限制

此示例的关键是计算CLim的值,这会导致每个曲面使用包含适当颜色的colormap部分。

要计算CLim的新值,您需要知道

  • 色图的总长度(CmLength)

  • 用于每个轴的开始色图插槽(BeginSlot)

  • 每个轴使用的结束色图插槽(EndSlot)

  • 包含的图形对象的最小和最大CData值 在轴上。也就是说,确定了轴CLim属性的值 当CLimMode为auto(CDmin和CDmax)时,由MATLAB提供。

首先,定义子图区域并绘制曲面。

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)的总色图的百分比,然后计算在给定轴中的CData范围时使用色卡图部分所需的CLim范围。最后,它确定计算的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值始终映射到colormap中的第一个颜色,并且最大CLim值始终映射到colormap中的最后一个颜色,无论是否确实存在与这些颜色对应的任何CData值。因此,如果指定CLim的值超出对象的实际CData最小值或最大值,则MATLAB仅使用色彩映射的子集为对象着色。

newclim函数计算CLim的值,该值将图形对象的实际CData值映射到您指定的开始和结束色彩映射槽。它通过定义具有计算的CLim值的“虚拟”图形对象来实现。