[英]2D Plotting a 3D point cloud as set of lines
我有一个三维点数组。 我需要将它们绘制在2D [x,z]网格上,其中每条线都基于范围内Y的值。 es。 第一行由0 <y <1的点组成,第二行由1 <y <2的点组成,依此类推。
我可以使用此脚本很好地绘制点(要获得外观更好的图形,我还可以通过在rgb三元组内部移动来更改每个点集的颜色)。 设置是线的范围(在我的情况下,Y是时间,我需要每0.1秒绘制一次)。 我是我的点数组的索引。
w= 0;
yend = 100;
set = 0.1;
numberOfColors = 1/2*(Yinterval)*(1/set);
incrementOfColor = 1/numberOfColors;
red = 0;
green = 0;
blue = 1;
color=[red green blue];
while w < yend
while y(i)>w&&y(i)<w+set
figure(1)
hold on
plot(x(i),z(i),'.','Color',color);
hold on
i=i+1;
end
w=w+set;
if red < 1-incrementOfColor && blue > 0
red = red + incrementOfColor;
blue = blue - incrementOfColor;
end
if red > incrementOfColor && blue < incrementOfColor
red = red-incrementOfColor;
green = green + incrementOfColor;
blue = 0;
end
color = [red green blue];
end
结果是: http : //i.imgur.com/HTyzWai.png当数据太多时,该图变得难以阅读,而数据太少则孤立的点并不能说明什么。 我试过将“设置”间隔内的点转换为数组,但确实无法解决:
while w < yend
while y(i)>w&&y(i)<w+set
vX(a,:)=x(i);
vZ(a,:)=z(i);
i=i+1;
a=a+1;
end
figure(2)
hold on
plot(vX,vZ,'-','Color',color);
给出此结果:imgur.com/S7OasUn.jpg
我的转换错误还是数组不是处理此问题的正确方法? 如果是这样,我应该怎么用?
我对Matlab还是比较陌生,所以如果这确实很明显,或者我以错误的方式提出了疑问,请原谅。
编辑:这是我想要实现的结果:
imgur.com/jPZTO8E.png,它是使用Origin的轮廓轮廓工具获得的。 我想你是用功能示例来说明这个意思的:
myPoints[i]:
i=0, x = 1, y= 0.03, z = 1
i=1, x = 2, y= 0.06, z = 3
i=2, x = 2.5, y = 0.09, z = 4
i=3, x = 1.2, y = 1.01, z = 3.1
i=4, x = 1.3, y = 1.04, z = 1.1
i=5, x = 1.2, y = 1.06, z = 2.5
i=6, x = 2, y = 1.09, z = 3.1
i=7, x = 1.2, y = 2.02, z = 3.1
等等..
我希望将点i 0,1,2绘制为一条线,将i 3,4,5绘制为另一条线,将i 7等绘制为第三条线。 根据我的数据,我有很多观点。
这是我正在使用的数据的一个示例。 https://drive.google.com/file/d/0B9GHAkIYepQcRXdBdy03dFJtT1k/view?usp=sharing其中:
x = myPoints(:,1);
y = myPoints(:,2);
z = myPoints(:,3);
在这种情况下,我只关心y值在85.85和90.85之间的点,并且我想每0.1边“放置一条边”(?)
x = myPoints(:,1);
y = myPoints(:,2);
z = myPoints(:,3);
ymin = 85.85;
ymax = 90.85;
set = 0.1;
nbins = (ymax-ymin)/set;
binedge = linspace(ymin, ymax, (nbins + 1));
我想我了解您要完成的工作,并且相信您可以通过向量化使用plot
来完成任务,而不必遍历每个要点。
给定您的示例数据,我们可以尝试一下此方法:
load('mypoints.mat');
x = myPoints(:,1);
y = myPoints(:,2);
z = myPoints(:,3);
% Bin your data by y values
ymin = 85.85;
ymax = 90.85;
set = 0.1;
nbins = (ymax-ymin)/set;
binedge = linspace(ymin, ymax, (nbins + 1));
[~, ~, binidx] = histcounts(y, binedge);
binloop = unique(binidx);
% Fix for error with unique. If you try to use a for loop with a column
% vector it passes the whole vector as your iterator, so you need to
% transpose it to a row vector.
temp = size(binloop);
if temp(1) ~= 1
binloop = binloop';
end
% Plot
figure
hold on
for ii = binloop
if ii == 0
% These fall outside of our bins, don't plot them
continue
else
dataidx = find(binidx == ii);
% Plot has its own color cycle, or you can add your color changing logic to this loop
plot(x(dataidx), z(dataidx), '-', 'LineWidth', 0.25);
end
end
hold off
我在这里所做的是利用histcounts
的第三个输出来对y
数据进行histcounts
,并为y
向量中的每个值返回一个histcounts
索引。
分解一下代码:
定义垃圾箱边界:
ymin = 85.85;
ymax = 90.85;
set = 0.1;
nbins = (ymax-ymin)/set;
binedge = linspace(ymin, ymax, (nbins + 1));
linspace
调用返回每个数据仓的边缘。 给定您的示例数据,我们得到binedge = [86.85, 86.95, 86.05, ..., 90.85]
。 然后,我们将这些边和y
向量插入到histcounts
以获得bin索引:
[~, ~, binidx] = histcounts(y, binedge);
根据文档定义垃圾箱的位置:
如果edge(k)≤X(i)<edges(k + 1),则值X(i)在第k个bin中。 最后一个面元还包括右边的面元边缘,因此如果edges(end-1)≤X(i)≤edges(end),则它包含X(i)。
我们可以使用unique
来遍历存在的所有bin。 我们可以在MATLAB的逻辑索引中利用find
来绘制每个循环迭代中来自单个bin的所有数据。 我忽略了ii == 0
因为它表示数据不属于其中一个箱(在MATLAB中0
索引是没有意义的)。
我还尝试了一些线条大小,以使图更易于阅读。 这里有很多数据可以可视化,但有帮助。 由于x值会回卷,因此您需要对数据进行一些修剪,但这应该是微不足道的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.