加速ListLinePlot

时间:2011-07-02 23:11:58

标签: wolfram-mathematica plot

我正在尝试使用Mathematica来分析一些原始数据。我希望能够使用ManipulateListLinePlot动态显示我感兴趣的数据范围,但是绘图渲染非常慢。我怎样才能加快速度?

以下是一些其他细节。外部文本文件存储原始数据:第一列是时间戳,第二列,第三列和第四列是数据读数,例如:

1309555993069, -2.369941, 6.129157, 6.823794
1309555993122, -2.260978, 6.170018, 7.014479
1309555993183, -2.070293, 6.129157, 6.823794
1309555993242, -1.988571, 6.238119, 7.123442

单个数据文件最多包含2·10 6 行。例如,要显示第二列,我使用:

x = Import["path/to/datafile"];
ListLinePlot[x[[All, {1, 2}]]]

此操作的执行时间长得令人难以忍受。为了显示可变范围的数据,我尝试使用Manipulate

Manipulate[ListLinePlot[Take[x, numrows][[All, {1, 2}]]], {numrows, 1, Length[x]}]

此指令有效,但当我尝试显示超过几千行时,它会快速爬行。我怎样才能加快速度?

其他一些细节:

  • MATLAB几乎可以立即在同一台计算机上显示相同数量的数据,因此原始数据大小不应成为问题。
  • 我已经尝试关闭图形抗锯齿功能,但它根本不会影响渲染速度。
  • 使用DataRange来避免Take无效。
  • 使用MaxPlotPoints会过多地扭曲情节。
  • Take中不使用Manipulate无效。
  • 渲染似乎需要花费大量时间。正在运行Timing[ListLinePlot[Take[x,100000][[All, {1, 2}]]]]会返回0.33:这意味着Take的评估本身几乎是即时的,是情节渲染会减慢所有内容。
  • 我正在使用fglrx驱动程序在Ubuntu Linux 11.10上运行Mathematica。强迫Mathematica使用mesa驱动程序没有帮助。

任何提示?

4 个答案:

答案 0 :(得分:11)

如果您的目标是快速但正确地显示您的数据,您可以使用我经常使用的以下技巧。

我将数据划分为大致相当于我的屏幕分辨率的块数(通常为1000或更少),无论如何都无法显示更多细节。然后我确定每个块的最小值和最大值,并从最小值到最大值到最小值到最大值绘制一条曲折线......结果看起来与原始数据完全一样。但是,您可以不“放大”,因为您会看到之字形线(例如,在导出到高分辨率pdf时)。然后你需要使用更多的块。

rv = RandomVariate[ExponentialDistribution[2], 100000];

ListLinePlot[rv, PlotRange -> All] (* original, slow *)
ListLinePlot[rv, PlotRange -> All, MaxPlotPoints -> 1000] (* fast but distorted *)

numberOfBlocks = 1000;

ListLinePlot[Riffle @@ Through[{Min /@ # &, Max /@ # &}[
   Partition[rv,Floor[Length[rv]/numberOfBlocks]]]], PlotRange -> All]

您可以添加DataRange->{...}选项以正确标记x轴。

希望这有帮助!

编辑: 另请参阅Mathematica Stackexchange上的类似问题: https://mathematica.stackexchange.com/q/140/58

答案 1 :(得分:7)

我没有在我的机器上对此进行过广泛测试(我有一台Mac,所以我不能排除特定于Linux的问题)。但是我发现了几点。以下对我来说非常快,但明显比数据集较小时要慢。您正在绘制数十万个数据点。

data = Accumulate@RandomVariate[NormalDistribution[], 200000];
Manipulate[ListLinePlot[Take[data, n]], {n, 1, Length[data]}]
  1. Manipulate中,您允许Take显示的数据量随意变化。请尝试每100个左右点增加numrows,因此渲染的次数较少。
  2. 尝试使用ContinuousAction->False选项(请参阅documentation)(我看到@Szabolcs的想法与我输入的内容相同。
  3. 我即将建议MaxPlotPoints,而是尝试使用PerformanceGoal ->"Speed"选项。 (见documentation

答案 2 :(得分:5)

我还注意到偶尔使用Mathematica渲染图形需要很长时间。实际上它必须是从Mathematica Graphics表达式到一些其他表示的一些转换步骤,因为一旦渲染,调整大小(并因此重新渲染)图形要快得多。对于许多示例而言,版本6之前的图形渲染曾经更快(但也缺少6+以上的许多功能)。

关于你能做什么的一些想法:

  1. 使用MaxPlotPoints的{​​{1}}选项在绘图前减少数据。如果它的下采样,它看起来可能没有区别。 ListLinePlot选项应该选择缩减采样算法,但我找不到任何文档(任何人?)

  2. Method中使用ContinuousAction -> False阻止它在您拖动滑块时实时重新计算所有内容。

答案 3 :(得分:5)

此处的另一个想法是使用Ramer–Douglas–Peucker algorithm在绘图之前减少数据点的数量。这可能会更好地保留数据的形状。我不知道你是否还需要这个,所以我不会提供实现。