Matlab:如何将不同的颜色图/颜色条分配给同一图中的不同表面

发布于 2024-12-15 05:19:18 字数 1323 浏览 5 评论 0原文

我对 Matlab 相当陌生,有几个问题。 我在同一个图中得到了两个曲面和一个平面。 我想对 b 使用不同的颜色图和颜色条,对 c 使用另一个颜色图和颜色条。 s 是固定颜色,所以这不是问题。

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

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

cmap2=colormap(redwhitegreen)

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

b=surf(x,y,z,cdata1)

颜色条,使用 z 值表示 b

c=pcolor(x,y,(z-z0))< /strong> - 我想为此使用 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)`

此时我遇到的问题将颜色图设置为 b 的 redwhitegreen,b 的 colorbar 我无法获得带有自己的 clim 等的第二个颜色条。

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

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

任何帮助表示赞赏。

I am fairly new to Matlab and have a few questions.
I got two surfaces and a plane in the same figure.
I want to use different colormap and colorbar for b and another colormap and colorbar for c. s is fixed color so it's not a problem.

Let me try to explain what I am trying to achieve:

cmap1=colormap(topobathy) -->cmap1 is 64x3 double as expected

cmap2=colormap(redwhitegreen)

create cdata1 using cmap1 (this is the first part I cannot figure out, how to scale z data using cmap1, by default CData contains the z values)

b=surf(x,y,z,cdata1)

colorbar for b using z values

c=pcolor(x,y,(z-z0)) - I want to use cmap2 for this one.

colorbar for c using (z-z0) values

Here is what I have so far and the problems I encounter

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)`

at this point colormap is set to redwhitegreen for b, colorbar of b
I can't get the second colorbar with its own clim etc.

I used the freezeColors and cbfreeze explained in this link:
http://blogs.mathworks.com/pick/2009/07/24/using-multiple-colormaps-in-a-single-figure/

but one thing works while messing another thing (probably all my fault). I want to learn how to have complete control over my objects without using external m files anyway.

Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

§普罗旺斯的薰衣草 2024-12-22 05:19:18

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

MathWorks 网站上有一个优秀指南解释了这一切(甚至像您的示例一样使用 surf()pcolor() ):

< a href="http://www.mathworks.com/support/tech-notes/1200/1215.html#Example_1" rel="noreferrer">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)

在此处输入图像描述

The basic idea is that you concatenate the colormaps, and then shift/scale the color data (CData) of the different plot handles to line up with the desired portions of the colormap. So, without knowing what your custom functions or specific data are, you could do something like colormap(topobathy(64); redwhitegreen(64)) and then scale the CData of b into the range [1,64] and the CData of c into the range [65,128].

There is an excellent guide on the MathWorks website that explains all this (even uses surf() and pcolor() like your example):

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

For the colorbar, you can just fake out the ticks and labels in a similar manner. Here is rough shot at making a color bar for the above example:

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

弱骨蛰伏 2024-12-22 05:19:18

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

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

    <块引用>

    cmap1 = 喷射(64); cmap2 = 铜(64);颜色图 = [cmap1 ; cmap2];

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

  2. 标准化数据,为 Axes1 的数据提供从 0 到 1 的范围,为 Axes2 的数据提供从 1 到 2 的范围。因此,Axes1 在 [0, 1] 中,Axes2 在 [1 2] 中。

    <块引用>

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

    对于Axes 2的数据集:

    <块引用>

    data2 = data2 - lower_limit;
    数据2 = 双精度(数据2./(上限2 - 下限2)) + 1;
    
  3. 代表他们时:

    • 轴1:

    <块引用>

    pcolor(handle_axes1, x_axis, y_axis, data1);着色(handle_axes1,'平面'); 
    caxis(handle_axes1, [0 2]);
    
    % 颜色条
    h_colorbar = colorbar('peer',handle_axes1);
    设置(h_colorbar,'YLim',[0 1]);
    
    标签 = num2str(linspace(lower_limit1, upper_limit1, 6)', 2);
    设置(h_colorbar, 'YTick', linspace(0, 1, 6));
    设置(h_colorbar,'YTickLabel',标签);
    

    • 轴2:

    <块引用>

    pcolor(handle_axes2, x_axis, y_axis, data2);着色(handle_axes2,'平面'); 
    caxis(handle_axes2, [0 2]);
    
    % 颜色条
    h_colorbar2 = colorbar('peer',handle_axes2);
    设置(h_colorbar2,'YLim',[1 2]);
    
    标签 = num2str(linspace(lower_limit2, upper_limit2, 6)', 2);
    set(h_colorbar2, 'YTick', linspace(1, 2, 6));
    设置(h_colorbar2,'YTickLabel',标签);
    

根据您的需要使用 pcolor 或 surf。
希望有帮助!

I had the same problem as you, and the best (and only) solution I found was the next:

  1. Concatenate both colormaps I wanted:

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

    So, the first colormap (cmap1) will be used for Axes1, and the second colormap (cmap2) for Axes2. I guess that Axes1 and Axes2 are in the same figure.

  2. Normalize data, giving a scale from 0 to 1 for data of Axes1, and from 1 to 2 for data of Axes2. So, Axes1 in [0, 1] and Axes2 in [1 2].

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

    For data set of Axes 2:

    data2 = data2 - lower_limit;
    data2 = double(data2./(upper_limit2 - lower_limit2)) + 1;
    
  3. When representing them:

    • 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);
    

Use pcolor or surf, depending on your needs.
Hope it helps!

坠似风落 2024-12-22 05:19:18

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

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

计算颜色限制

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

要计算 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 值始终映射到颜色图中的第一个颜色,最大 CLim 值始终映射到颜色图中的最后一个颜色,无论是否确实存在与这些颜色对应的 CData 值。因此,如果您指定的 CLim 值超出了对象的实际 CData 最小值或最大值,MATLAB 将仅使用颜色图的子集为对象着色。

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

Matlab has provided code for a function newclim which solves this problem cleanly by concatenating the colormaps into one colormap. I could only find this documentation on the 2012b Help, but not online.

Note that the axes used to update the CLim as the last step could be axes to surf plots, which is how I applied this code.

Calculating Color Limits

The key to this example is calculating values for CLim that cause each surface to use the section of the colormap containing the appropriate colors.

To calculate the new values for CLim, you need to know

  • The total length of the colormap (CmLength)

  • The beginning colormap slot to use for each axes (BeginSlot)

  • The ending colormap slot to use for each axes (EndSlot)

  • The minimum and maximum CData values of the graphic objects contained
    in the axes. That is, the values of the axes CLim property determined
    by MATLAB when CLimMode is auto (CDmin and CDmax).

First, define subplot regions and plot the surfaces.

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')

Concatenate two colormaps and install the new colormap.

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

Obtain the data you need to calculate new values for 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');

Defining a Function to Calculate CLim Values

Computing new values for CLim involves determining the portion of the colormap you want each axes to use relative to the total colormap size and scaling its Clim range accordingly. You can define a MATLAB function to do this.

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

The input arguments are identified in the bulleted list above. The function first computes the percentage of the total colormap you want to use for a particular axes (PCmRange) and then computes the CLim range required to use that portion of the colormap given the CData range in the axes. Finally, it determines the minimum and maximum values required for the calculated CLim range and returns these values. These values are the color limits for the given axes.

Using the Function

Use the newclim function to set the CLim values of each axes. The statement

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

sets the CLim values for the first axes so the surface uses color slots 65 to 120. The lit surface uses the lower 64 slots. You need to reset its CLim values as well.

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

How the Function Works

MATLAB enables you to specify any values for the axes CLim property, even if these values do not correspond to the CData of the graphics objects displayed in the axes. The minimum CLim value is always mapped to the first color in the colormap and the maximum CLim value is always mapped to the last color in the colormap, whether or not there are really any CData values corresponding to these colors. Therefore, if you specify values for CLim that extend beyond the object's actual CData minimum or maximum, MATLAB colors the object with only a subset of the colormap.

The newclim function computes values for CLim that map the graphics object's actual CData values to the beginning and ending colormap slots that you specify. It does this by defining a "virtual" graphics object having the computed CLim values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文