如何在 Matlab 中更新散点图(循环)
How to update a scatter3 plot (in a loop) in Matlab
一个非常简单的问题,但无法在网上找到答案...我想可视化从激光雷达收集的点云。我可以绘制单个帧,但想循环它们以创建 "animation"。我知道如何使用 drawnow 对普通图执行此操作,但无法使用 scatter3 进行操作。如果我像在注释代码中所做的那样简单地再次调用 scatter3,那么我在散点图中查看的帧会随着每次更新而跳来跳去(非常不舒服)。如何在不更改散点图即 UI 的情况下让 scatter3 图更新到新点。仍然能够在可视化点云循环时对其进行平移和缩放。
编辑:该文件是一个 rosbag 文件,我无法附加它,因为它有 170MB。在带有普通数组的循环中使用 scatter3 时,问题不会发生似乎与使用 scatter3 使用 frame = readMessages(rawBag, i).
调用 PointCloud2 类型文件有关
编辑:问题似乎不在于轴限制,而在于图中轴的视图 window。当散点图初始化时,它的正 x 在右侧,正 y 在屏幕外,正 z 向上,如视图 1 所示。然后过了一会儿,它跳到第二个视图,其中轴有更改后,正 x 现在在屏幕外,正 y 向右,正 z 向上(图中显示了两个视图)。这使得无法在循环中查看,因为它不断切换。所以基本上如何在不调用 scatter3(pointCloudData)?
的情况下更新绘图
rawBag = rosbag('jackwalking.bag');
frame = readMessages(rawBag, 1);
scatter3(frame{1});
hold on
for i = 1:length(readMessages(rawBag))
disp(i)
frame = readMessages(rawBag, i);
% UPDATE the 3D Scatter %
% drawnow does not work?
% Currently using:
scatter3(frame{1})
pause(.01)
end
据我了解你所说的 "plots jumpying around",原因是 x
、y
、z
的自动调整限制 scatter3
情节。您可以将 XLimMode
、YLimMode
、ZLimMode
行为更改为 manual
以强制轴保持固定。不过,您必须提供初始轴限制。
% Mock data, since you haven't provided a data sample
x = randn(200,50);
y = randn(200,50);
z = randn(200,50);
% Plot first frame before loop
HS = scatter3(x(:,1), y(:,1), z(:,1));
hold on
% Provide initial axes limits (adjust to your data)
xlim([-5,5])
ylim([-5,5])
zlim([-5,5])
% Set 'LimModes' to 'manual' to prevent auto resaling of the plot
set(gca, 'XLimMode', 'manual', 'YLimMode', 'manual', 'ZLimMode', 'manual')
for i=2:len(x,2)
scatter3(x(:,i), y(:,i), z(:,i))
pause(1)
end
这会生成 "animation" 个图,您可以在其中平移和放大数据,同时在循环中添加连续点
诀窍是不要在动画中使用 scatter
或 plot
等函数,而是修改已经存在的绘图中的数据。这些函数总是重置轴属性,这就是您看到视图重置的原因。修改现有绘图时,坐标轴不受影响。
函数scatter3
(与所有绘图函数一样)returns 绘制绘图的图形对象的句柄。在 scatter3
的情况下,此句柄具有三个感兴趣的属性:XData
、YData
和 ZData
。您可以更新这些属性以更改点的位置:
N = 100;
data = randn(N,3) * 40;
h = scatter3(data(:,1),data(:,2),data(:,3));
for ii = 1:500
data = data + randn(N,3);
set(h,'XData',data(:,1),'YData',data(:,2),'ZData',data(:,3));
drawnow
pause(1/5)
end
新的 data
也可以完全不同,它甚至不需要包含相同数量的点。
但是当修改这三个属性时,你会看到坐标轴的XLim
、YLim
和ZLim
属性发生了变化。也就是说,轴将重新缩放以容纳所有数据。如果您需要防止这种情况发生,请将轴的 XLimMode
、YLimMode
和 ZLimMode
设置为 'manual'
:
set(gca,'XLimMode','manual','YLimMode','manual','ZLimMode','manual')
手动设置限制时,限制模式始终设置为手动。
一个非常简单的问题,但无法在网上找到答案...我想可视化从激光雷达收集的点云。我可以绘制单个帧,但想循环它们以创建 "animation"。我知道如何使用 drawnow 对普通图执行此操作,但无法使用 scatter3 进行操作。如果我像在注释代码中所做的那样简单地再次调用 scatter3,那么我在散点图中查看的帧会随着每次更新而跳来跳去(非常不舒服)。如何在不更改散点图即 UI 的情况下让 scatter3 图更新到新点。仍然能够在可视化点云循环时对其进行平移和缩放。
编辑:该文件是一个 rosbag 文件,我无法附加它,因为它有 170MB。在带有普通数组的循环中使用 scatter3 时,问题不会发生似乎与使用 scatter3 使用 frame = readMessages(rawBag, i).
调用 PointCloud2 类型文件有关编辑:问题似乎不在于轴限制,而在于图中轴的视图 window。当散点图初始化时,它的正 x 在右侧,正 y 在屏幕外,正 z 向上,如视图 1 所示。然后过了一会儿,它跳到第二个视图,其中轴有更改后,正 x 现在在屏幕外,正 y 向右,正 z 向上(图中显示了两个视图)。这使得无法在循环中查看,因为它不断切换。所以基本上如何在不调用 scatter3(pointCloudData)?
的情况下更新绘图rawBag = rosbag('jackwalking.bag');
frame = readMessages(rawBag, 1);
scatter3(frame{1});
hold on
for i = 1:length(readMessages(rawBag))
disp(i)
frame = readMessages(rawBag, i);
% UPDATE the 3D Scatter %
% drawnow does not work?
% Currently using:
scatter3(frame{1})
pause(.01)
end
据我了解你所说的 "plots jumpying around",原因是 x
、y
、z
的自动调整限制 scatter3
情节。您可以将 XLimMode
、YLimMode
、ZLimMode
行为更改为 manual
以强制轴保持固定。不过,您必须提供初始轴限制。
% Mock data, since you haven't provided a data sample
x = randn(200,50);
y = randn(200,50);
z = randn(200,50);
% Plot first frame before loop
HS = scatter3(x(:,1), y(:,1), z(:,1));
hold on
% Provide initial axes limits (adjust to your data)
xlim([-5,5])
ylim([-5,5])
zlim([-5,5])
% Set 'LimModes' to 'manual' to prevent auto resaling of the plot
set(gca, 'XLimMode', 'manual', 'YLimMode', 'manual', 'ZLimMode', 'manual')
for i=2:len(x,2)
scatter3(x(:,i), y(:,i), z(:,i))
pause(1)
end
这会生成 "animation" 个图,您可以在其中平移和放大数据,同时在循环中添加连续点
诀窍是不要在动画中使用 scatter
或 plot
等函数,而是修改已经存在的绘图中的数据。这些函数总是重置轴属性,这就是您看到视图重置的原因。修改现有绘图时,坐标轴不受影响。
函数scatter3
(与所有绘图函数一样)returns 绘制绘图的图形对象的句柄。在 scatter3
的情况下,此句柄具有三个感兴趣的属性:XData
、YData
和 ZData
。您可以更新这些属性以更改点的位置:
N = 100;
data = randn(N,3) * 40;
h = scatter3(data(:,1),data(:,2),data(:,3));
for ii = 1:500
data = data + randn(N,3);
set(h,'XData',data(:,1),'YData',data(:,2),'ZData',data(:,3));
drawnow
pause(1/5)
end
新的 data
也可以完全不同,它甚至不需要包含相同数量的点。
但是当修改这三个属性时,你会看到坐标轴的XLim
、YLim
和ZLim
属性发生了变化。也就是说,轴将重新缩放以容纳所有数据。如果您需要防止这种情况发生,请将轴的 XLimMode
、YLimMode
和 ZLimMode
设置为 'manual'
:
set(gca,'XLimMode','manual','YLimMode','manual','ZLimMode','manual')
手动设置限制时,限制模式始终设置为手动。