如何创建一个有两种颜色和特定断点的颜色条Matlab

6xfqseft  于 2023-01-13  发布在  Matlab
关注(0)|答案(3)|浏览(209)

对于最终的3D表面输出,我需要显示两种颜色的图例,X〉breakpoint为蓝色,Y〈breakpoint为绿色。我已经能够绘制这两种颜色的图,但很难弄清楚如何根据我的断点分割图例。
我一直在使用色彩Map工具,但没有成功,因为它仍然没有使用我定义的断点。颜色需要两个定义的区域没有阴影。

surf(xa,ya,Profile,'EdgeColor','none')
breakpoint = 1;
colors = [0 0 1; 0 1 1];
colormap(colors);
colorbar
e1xvtsh3

e1xvtsh31#

获取仅有2种颜色的表面的一种方法是使用surf(...)函数的Color参数。
您可以构建一个颜色矩阵ColorData,大小与数据相同,只有2个值:

  • 其中,配置文件〈breakpoint =〉颜色数据=0
  • 其中配置文件〉=断点=〉颜色数据=1

然后,如果使用指定的颜色参数绘制曲面,并应用2色颜色Map表,则所有级别将自行调整。
然而,如果我们让它像现在的colorbar标记无效,他们从0到1,而不是显示完整的数据范围。这是确定的,虽然,你可以创建一组有意义的标签和覆盖默认的。
代码如下所示(感谢Wolfie提供的演示数据):

% Set up a quick surface ( Thank you Wolfie :-) )
[xa,ya] = meshgrid( pi:0.1:2*pi, 0:0.1:2*pi );
Profile = cos(xa) * 2 + sin(ya) + 1;

%% define colormap and breakpoint
cmap = [0 1 0 ; 0 1 1];    
breakpoint = 1 ;

%% create a color matrix with only 2 values:
%   where Profile < breakpoint => ColorData=0
%   where Profile > breakpoint => ColorData=1
ColorData= zeros(size(Profile)) ;
ColorData(Profile>=breakpoint) = 1 ;

%% Plot the surface, specifying the color matrix we want to have applied
hs = surf( xa, ya, Profile, ColorData ) ;
colormap(cmap) ;
hb = colorbar ;

%% Now adjust colorbar ticks and labels
cticks = [0.25 0.5 0.75] ; % positions of the ticks we keep

% build labels
bpstr = num2str(breakpoint) ;
cticklabels = {['<' bpstr] ; bpstr ; ['>' bpstr]}

% apply
hb.Ticks = cticks ;
hb.TickLabels = cticklabels ;

breakpoint=1breakpoint=1.75的结果如下所示:

这种方法的缺点是,在颜色条上,断点总是位于颜色条的中间,即使实际断点更接近数据值的下限或上限。

9rygscc1

9rygscc12#

您需要给予一个包含更多点的颜色贴图,特别是以断点为中心的贴图的“中间颜色”,但该颜色位于颜色贴图中相对于曲面最小值和最大值的正确点。
因此,如果您所需的断点是曲面最小值和最大值之间的1/4,您可以拥有一个100行的颜色Map,其中第25行包含中间/断点颜色。
你可以通过从一个包含断点的数组插入到具有一致间隔的数组来实现。请看下面的注解代码

% Set up a quick surface
[xa,ya] = meshgrid( pi:0.1:2*pi, 0:0.1:2*pi );
prof = cos(xa) * 2 + sin(ya) + 1;
figure(1); clf;
surf( xa, ya, prof );

% Set the breakpoint value
breakpoint = 1;
% Get the min and max values of the mesh, need this for scaling
minp = min( prof(:) );
maxp = max( prof(:) );
% Set up the colour map from a start and end colour
cstart = [0,0,1];
cend = [0,1,1];
% The average colour should happen at the breakpoint, so calculate it
cavg = mean( [cstart; cend] );
% Set up an interpolation, from our non-uniform colour array including the
% breakpoint to a nice evenly spaced colour map which changes the same
colours = [cstart; cavg; cend];
breakpoints = [minp; breakpoint; maxp];
colours = interp1( breakpoints, colours, linspace(minp,maxp,100) );

% Set the colour map
colormap( colours );
colorbar;

如果您想要“清晰”的轮廓而不是梯度,则可以更改interp1的设置以使用先前的插值而不是线性插值

colours = interp1( breakpoints, colours, linspace(minp,maxp,100), 'previous', 'extrap' );

breakpoint = 2的绘图

breakpoint = -1的绘图

breakpoint = 1的绘图,但使用最接近插值而非线性插值

您可以稍微压缩代码中的颜色Map生成部分,但我认为这会使其不太清楚发生了什么

% Set the breakpoint value
breakpoint = 1;
% Get the min and max values of the mesh, need this for scaling
minp = min( prof(:) );
maxp = max( prof(:) );
% Get the interpolated ratio of one colour vs the other
ratio = interp1( [minp,breakpoint,maxp], [0,0.5,1], linspace(minp,maxp,100) ).';
% Create colour map by combining two colours in this ratio
colours = [0,0,1].*(1-ratio) + [0,1,1].*ratio;
30byixjq

30byixjq3#

可以使用caxis或ax.CLim将颜色Map表居中放置在断点周围,然后使用其Limits属性重置颜色条轴。

[X,Y,Z] = peaks(50);
surf(X,Y,Z)
colormap([0 1 0;0 1 1])
breakpoint = 3;

% This
caxis([-.1 .1]+breakpoint)

% Or this
% ax = gca;
% ax.CLim = [-.1 .1]+breakpoint;

cb = colorbar;
cb.Limits = [min(Z,[],'all'),max(Z,[],'all')];

相关问题