12

我对 Matlab 还很陌生,有几个问题。我在同一个图中有两个表面和一个平面。我想为 b 使用不同的颜色图和颜色条,为 c 使用另一个颜色图和颜色条。s 是固定颜色,所以这不是问题。

让我试着解释一下我想要达到的目标:

cmap1=colormap(topobathy) --> cmap1 是 64x3 的两倍,如预期的那样

cmap2=颜色图(红白绿)

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

b=冲浪(x,y,z,cdata1)

使用z值的 b 的颜色条

c=pcolor(x,y,(z-z0)) - 我想使用 cmap2 这个。

使用 (z- z0 ) 值的 c 的颜色条

这是我到目前为止所拥有的以及我遇到的问题

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 的颜色图设置为 redwhitegreen,b 的颜色条我无法获得具有自己的 clim 等的第二个颜色条。

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

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

任何帮助表示赞赏。

4

3 回答 3

18

基本思想是连接颜色图,然后移动/缩放CData不同绘图句柄的颜色数据 ( ) 以与颜色图的所需部分对齐。因此,在不知道您的自定义函数或特定数据是什么的情况下,您可以执行类似的操作colormap(topobathy(64); redwhitegreen(64)),然后将 of 缩放CDatab范围 [1,64] 并将CDataofc缩放到范围 [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)

在此处输入图像描述

于 2011-11-10T06:34:15.280 回答
1

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

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

    cmap1 = 喷气机(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。

    数据1 = 数据1 - 下限1;data1 = double(data1./(upper_limit1 - lower_limit1));

    对于轴 2 的数据集:

    data2 = data2 - lower_limit;
    data2 = double(data2./(upper_limit2 - lower_limit2)) + 1;
    
  3. 代表他们时:

    • 轴1:
    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。希望能帮助到你!

于 2014-07-23T08:10:22.240 回答
1

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

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

计算颜色限制

此示例的关键是计算 CLim 的值,使每个表面使用包含适当颜色的颜色图部分。

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

  • 颜色图的总长度(CmLength)

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

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

  • 坐标区中包含的图形对象的最小和最大 CData 值。也就是说,当 CLimMode 为 auto 时,由 MATLAB 确定的轴 CLim 属性的值(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) 的总颜色图的百分比,然后在给定轴中的 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 值始终映射到颜色图中的第一种颜色,而最大 CLim 值始终映射到颜色图中的最后一种颜色,无论是否真的有任何 CData 值对应于这些颜色。因此,如果您为 CLim 指定的值超出对象的实际 CData 最小值或最大值,MATLAB 将仅使用颜色图的子集为对象着色。

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

于 2015-02-20T17:18:37.353 回答