[英]Produce a 3D stem plot with a custom colormap in MATLAB
我有一个矩阵(200 x 4),其中前三个值是X
, Y
和Z
数据。 我想使用第四列来显示每个(X,Y,Z)
三元组,以便它映射到一种颜色。
第四列包含从0.0到1.0的值(200个值)。 我想手动和线性地使用colormap映射这些值。 最小值应为蓝色,最大值应为红色。
我知道scatter3
是可能的。 但是,我想使用stem3
,在这里我可以从colormap中手动指定颜色。
在MATLAB中有没有办法做到这一点?
这很简单。 kkuilla发布了一个非常有见地的链接。 首先,如果要创建一个从蓝色到红色的颜色映射表,则需要将图像分解为三种颜色:红色,绿色和蓝色。
因此,您要做的就是改变红色和蓝色通道。 从纯蓝色开始,即RGB = (0,0,255)
,将其映射到w = 0
的初始权重,然后将其更改为RGB = (255,0,0)
且在w = 1
的末尾。 您可以通过linspace
轻松地做到这一点。 但是,对要在MATLAB中绘制的颜色图中的颜色进行了归一化处理,以使它们介于[0,1]
而非[0,255]
。 另外,由于MATLAB中的颜色图是N x 3
的矩阵,其中N
是所需的颜色总数,因此您要做的就是:
num_colours = 10;
colourmap = [linspace(0,1,num_colours).' zeros(num_colours,1) linspace(1,0,num_colours).'];
weights = linspace(0,1,num_colours);
num_colours
是您想要显示的颜色总数。 我将其设置为10以使您入门。 weights
是我们以后需要的东西,因此请不要担心这种精确性。 本质上, colormap
将是您应用于数据的颜色图。
但是,现在要困难的是,您正在绘制的数据与数据本身(或数据的第四列)的权重没有关联。 这意味着您不能简单地使用(X,Y,Z)
数据来确定stem
中每个图的颜色。 通常对于MATLAB中的颜色图,茎的高度与显示的颜色成比例。 对于数据中最大的Z
值,自然会将其分配给颜色图末尾的颜色,即红色。 数据中最小的Z
值自然会在颜色图的开头或蓝色处分配。
如果是这种情况,则只需要进行一次stem
调用并将颜色图指定为Color
的属性即可。 因为在高度之间没有相关性Z
价值,你的每一个数据点分配权重,你必须通过每个点无奈地循环 ,并确定每一个点的权重之间的最接近的值权重并最终将颜色映射到每种颜色,然后将此最接近的颜色分别应用于stem
每个点。
我们使用上面生成的weights
向量确定最接近的点。 我们可以认为每种颜色都有[0,1]
的映射,每种权重都对应于colourmap
的颜色。 因此,权重0是颜色图中的第一个颜色,即在第一行中。 此后的下一个权重是第二种颜色,该权重在第二行中,依此类推....所以我们只需要确定矩阵第四列中每个权重最接近上述weights
向量的位置。 这将确定我们需要从颜色图中选择哪种颜色来绘制点。
假设您的200 x 4
矩阵存储在data
,则必须专门这样做:
%// Spawn a new figure
figure;
%// Determine the number of points in the dataset
num_points = size(data,1);
%// For each point in the data set
for idx = 1 : num_points
%// Get 4th column element and determine closest colour
w = data(idx,4);
[~,ind] = min(abs(weights-w));
color = colourmap(ind,:);
%// Plot a stem at this point and change the colour of the stem
%// as well as the marker edge colour and face colour
stem3(data(idx,1), data(idx,2), data(idx,3), 'Color', color, ...
'MarkerEdgeColor', color, 'MarkerFaceColor', color);
%// Make sure multiple calls to stem don't clear the plot
hold on;
end
%// Display colour bar to show colours
colormap(colourmap(1:end-1,:));
colorbar('YTickLabel', colourmap);
最后两行有些黑,但是我们基本上在图的右侧显示了一个色条,告诉您每种重量如何映射到每种颜色。
让我们对一些数据进行测试。 我将生成一个随机的200 x 4
点矩阵,我们将使用上面的代码并使用stem3
进行stem3
:
rng(123123); %// Set seed for reproducibility
data = rand(200,4);
num_colours = 10;
我将唯一颜色的总数设置为10。一旦获得了上述数据,当我运行上述代码时,这就是我得到的图:
您也可以使用HSV
。 Z
值将对应于您的第四列。 Z
值低为蓝色, Z
值高为红色。
我使用http://colorizer.org/网站计算出,蓝色为H=0.65
,红色为H=1
。 S
和V
保持不变。
从http://colorizer.org/ ,我得到蓝色是H=236, S=100, V=100
。 那么蓝色的H
值为H = 235/360 = 0.65
,红色的H=1, S=1, V=1
。
num_elem = 200;
c = linspace(0,1,num_elem)'; % // Replace this with the values from your fourth column
% // The equation gives blue (H=0.65) for c=0 and red (H=1) for c = 1
H = 0.65 + ((1-0.65).* c);
S = ones(size(c,1),1);
V = ones(size(c,1),1);
% // You have to convert it to RGB to be compatible with stem3
colourmap = hsv2rgb([H,S,V]);
% // Generate some sample data
theta = linspace(0,2*pi,num_elem)';
X = cos(theta);
Y = sin(theta);
Z = theta;
% // Plot the sample data with the colourmap
figure;
hold on;
for idx=1:num_elem
stem3(X(idx),Y(idx),Z(idx),':*','Color',colourmap(idx,:) ...
,'MarkerEdgeColor',colourmap(idx,:) ...
,'MarkerFaceColor',colourmap(idx,:) ...
,'LineWidth',4 ...
);
end
hold off;
set(gca,'FontSize',36');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.