关于图:MATLAB scatter3,plot3速度差异

MATLAB scatter3, plot3 speed discrepencies

这是关于MATLAB如何花费截然不同的时间绘制同一件事的原因,以及原因。

我在3D空间中产生10000点:

1
2
3
X = rand(10000, 1);
Y = rand(10000, 1);
Z = rand(10000, 1);

然后,我使用四种不同方法之一对此进行绘制,以创建如下所示的图:

alt text

我关闭了所有数字并清除了每次运行之间的工作空间,以确保公平。

使用scatter3进行批量绘图:

1
2
>> tic; scatter3(X, Y, Z); drawnow; toc
Elapsed time is 0.815450 seconds.

使用scatter3进行个别绘图:

1
2
3
4
5
6
>> tic; hold on;
for i = 1:10000
    scatter3(X(i), Y(i), Z(i), 'b');
end
hold off; drawnow; toc
Elapsed time is 51.469547 seconds.

使用plot3进行批量绘图:

1
2
>> tic; plot3(X, Y, Z, 'o'); drawnow; toc
Elapsed time is 0.153480 seconds.

使用plot3进行个别绘图:

1
2
3
4
5
6
>> tic; hold on
for i = 1:10000
    plot3(X(i), Y(i), Z(i), 'o');
end
drawnow; toc
Elapsed time is 5.854662 seconds.

MATLAB在"更长的"例程中花了这么长时间在幕后做什么? 使用每种方法的优点和缺点是什么?

编辑:
多亏了Ben Voigt的建议(请参阅答案),我在时间中加入了drawnow命令-但这与时间没有多大区别。


为了更快的方法,请考虑以下第三个选项(直接使用低级函数LINE):

1
2
line([X,X], [Y,Y], [Z,Z], 'LineStyle','none', 'Marker','o', 'Color','b')
view(3)

以下是一些讨论绘图性能问题的文章:

  • 性能:散点与线
  • 情节表现


运行scatter3plot3所需时间之间的主要区别在于编译plot3而解释scatter3的事实(如您在编辑函数时所见)。如果scatter3也被编译,则速度差将很小。

循环绘制与一次性绘制之间的主要区别在于,您将绘制的手柄作为子代添加到坐标轴上(请查看get(gca,'Children')的输出),因此在循环中增加一个复杂的数组,我们都知道这很慢。此外,您经常调用多个函数,而不仅仅是一次调用,因此会导致函数开销。

重新计算轴限制在这里不是问题。如果你跑

1
2
3
4
for i = 1:10000
    plot3(X(i), Y(i), Z(i), 'o');
    drawnow;
end

这会迫使Matlab在每次迭代时更新图形(并且速度会慢很多),您会看到轴的限制根本没有改变(因为默认的轴限制为0和1)。但是,即使轴的限制以不同的方式开始,它们也不需要花费很多迭代即可收敛于这些数据。与省去hold on相比,这会减少绘制时间,因为在每一步都要重新计算轴。

为什么要有这些不同的功能? scatter3允许您在单个手柄下绘制具有不同标记大小和颜色的点,而您需要一个循环并使用plot3为每个点获得一个手柄,这不仅在速度上很昂贵,而且在记忆方面。但是,如果您需要分别与不同的点(或点组)进行交互-也许您想为每个点添加一个单独的图例条目,也许您希望能够分别打开和关闭它们,等等-使用plot3循环可能是最好的(尽管很慢)解决方案。


好吧,如果您想控制每个点的颜色,则散点图会更快,因为您需要分别调用图。

另外,由于您尚未调用drawnow,因此我不确定您的计时信息是否准确,因此实际绘制可能会在toc之后进行。

综上所述:

  • plot3最快,因为它在许多不同的位置绘制相同的标记
  • scatter3绘制许多不同的标记,因为标记的大小和颜色(允许)随每个点而变化
  • 调用一个循环真的很慢,因为参数解析等必须重复进行,此外,当将点添加到绘图中时,还必须重新计算轴