【问题标题】:How to update a scatter3 plot (in a loop) in Matlab如何在 Matlab 中更新 scatter3 图(在循环中)
【发布时间】:2019-06-10 02:44:08
【问题描述】:

一个很简单的问题,但在网上找不到答案...我想可视化从激光雷达收集的点云。我可以绘制单个帧,但想循环它们以创建“动画”。我知道如何使用 drawow 处理正常的绘图,但无法使用 scatter3。如果我像在注释代码中所做的那样再次调用 scatter3,那么我在散点图中查看的帧会随着每次更新而跳动(非常不舒服)。如何在不更改散点图 UI 的情况下让 scatter3 图更新到新点,即。在它循环通过时,仍然能够在可视化点云周围平移和缩放。

编辑:该文件是 rosbag 文件,我无法附加它,因为它是 170MB。使用 scatter3 在具有普通数组的循环中使用时不会发生问题,这似乎与使用 scatter3 使用 frame = readMessages(rawBag, i) 调用 PointCloud2 类型文件有关。

编辑:问题似乎不在于轴限制,而在于图形窗口中的轴视图。初始化散点图时,正 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

【问题讨论】:

  • 相关的代码是你删除的% UPDATE the 3D Scatter %下的东西。请在您的问题中包括这一点。理想情况下,您会提供一个小数据集和完整的代码来显示问题。见minimal reproducible example
  • 不幸的是,我无法共享数据,因为它是一个 170mb 的 .bag 文件。只有在使用 scatter3 绘制这种格式的数据时才会出现问题......如果有一种方法可以在不制作新的情况下更新绘图,那么解决我的问题是什么?
  • 请参阅herehereherehere 如何在不重复绘制数据的情况下为数据设置动画。这可能会解决记忆问题,并使您的轴不会“跳跃”。

标签: matlab matlab-figure point-clouds scatter3d


【解决方案1】:

据我了解,您所说的“情节跳跃”,其原因是 scatter3 情节的自动调整 x,y,z 限制。您可以将XLimModeYLimModeZLimMode 行为更改为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 

这会产生绘图的“动画”,您可以在其中平移和放大数据,同时在循环中添加连续点

【讨论】:

  • 感谢您的回答,问题似乎不是限制。我在我的问题和 2 个屏幕截图中添加了更多内容。
【解决方案2】:

诀窍是不要在动画中使用诸如scatterplot 之类的函数,而是修改绘图中已经存在的数据。这些函数总是重置坐标区属性,这就是您看到视图重置的原因。修改现有绘图时,轴不受影响。

函数scatter3(与所有绘图函数一样)返回渲染绘图的图形对象的句柄。在scatter3 的情况下,此句柄在此处具有三个感兴趣的属性:XDataYDataZData。您可以更新这些属性以更改点的位置:

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 也可以完全不同,甚至不需要包含相同数量的点。

但是在修改这三个属性的时候,你会看到坐标轴的XLimYLimZLim属性发生了变化。也就是说,轴将重新缩放以容纳所有数据。如果需要防止这种情况,请将坐标区的 XLimModeYLimModeZLimMode 设置为 'manual'

set(gca,'XLimMode','manual','YLimMode','manual','ZLimMode','manual')

手动设置限制时,限制模式始终设置为手动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 2017-02-11
    相关资源
    最近更新 更多