加快 ListLinePlot 速度

发布于 2024-11-18 11:38:46 字数 1329 浏览 3 评论 0原文

我正在尝试使用 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·106行。例如,为了显示第二列,我使用:

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 会使绘图扭曲太多而变得无用。
  • Manipulate 中不使用 Take 没有帮助。
  • 渲染似乎需要花费大量时间。运行 Timing[ListLinePlot[Take[x,100000][[All, {1, 2}]]]] 返回 0.33:这意味着 的计算Take 本身几乎是瞬时的,是情节渲染减慢了一切。
  • 我使用 fglrx 驱动程序在 Ubuntu Linux 11.10 上运行 Mathematica。强制 Mathematica 使用 mesa 驱动程序并没有帮助。

有什么提示吗?

I am trying to use Mathematica to analyse some raw data. I'd like to be able to dynamically display the range of data I'm interested in using Manipulate and ListLinePlot, but the plot rendering is extremely slow. How can I speed it up?

Here are some additional details. An external text file stores the raw data: the first column is a timestamp, the second, third and fourth columns are data readings, for example:

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

A single data file contains up to 2·106 lines. To display, for example, the second column, I use:

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

The execution time of this operation is unbearably long. To display a variable range of data I tried to use Manipulate:

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

This instruction works, but it quickly crawls when I try to display more than few thousand lines. How can I speed it up?

Some additional details:

  • MATLAB displays the same amount of data on the same computer almost instantaneously, thus the raw data size shouldn't be an issue.
  • I already tried to turn off graphics antialiasing, but it didn't impact rendering speed at all.
  • Using DataRange to avoid Take doesn't help.
  • Using MaxPlotPoints distorts too much the plot to be useful.
  • Not using Take in Manipulate doesn't help.
  • The rendering seems to take huge amount of time. Running Timing[ListLinePlot[Take[x,100000][[All, {1, 2}]]]] returns 0.33: this means that the evaluation of Take by itself is almost instantaneous, is the plot rendering that slows everything down.
  • I am running Mathematica on Ubuntu Linux 11.10 using the fglrx drivers. Forcing Mathematica to use mesa drivers didn't help.

Any hint?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

℡Ms空城旧梦 2024-11-25 11:38:46

如果您的目标只是快速而正确地可视化数据,则可以使用我经常使用的以下技巧。

我将数据划分为多个块,大致对应于我的屏幕分辨率(通常为 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

If your goal is to just visualize your data quickly but properly, you can use the following trick, which I am constantly using.

I partition the data into a number of blocks corresponding roughly to the resolution of my screen (usually 1000 or less), more detail cannot be displayed anyway. Then I determine the Min and Max of each block, and draw a zig-zag line from min to max to min to max... The result will look exactly like the original data. You can however not "zoom in", as you would then see the zig-zag line (e.g. when exporting to high-res pdf). Then you need to use a larger number of blocks.

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]

You can add the DataRange->{...} option to label the x-axis appropriately.

Hope this helps!

EDIT:
See also this similar question on Mathematica Stackexchange:
https://mathematica.stackexchange.com/q/140/58

撩动你心 2024-11-25 11:38:46

我还没有在我的机器上对此进行广泛的测试(我有一台 Mac,所以我不能排除 Linux 特定的问题)。但我想到了几点。以下对我来说相当快,但显然比数据集较小时慢。您正在绘制数十万个数据点。

data = Accumulate@RandomVariate[NormalDistribution[], 200000];
Manipulate[ListLinePlot[Take[data, n]], {n, 1, Length[data]}]
  1. Manipulate 中,您允许使用 Take 显示的数据量任意变化。尝试每 100 个点左右增加 numrows ,这样渲染的内容就会减少。
  2. 尝试使用 ContinouslyAction->False 选项(请参阅文档)(我发现 @Szabolcs 的想法与我输入的内容相同。
  3. 我本来打算建议 MaxPlotPoints,但请尝试使用 PerformanceGoal ->“速度” 选项(请参阅文档

I haven't tested extensively this on my machine (I have a Mac, so I can't rule out Linux-specific issues). but a couple of points occur to me. The following was pretty quick for me, but obviously slower than if the data set was smaller. You are plotting hundreds of thousands of data points.

data = Accumulate@RandomVariate[NormalDistribution[], 200000];
Manipulate[ListLinePlot[Take[data, n]], {n, 1, Length[data]}]
  1. In a Manipulate, you are allowing the amount of data shown with Take to vary arbitrarily. Try only incrementing numrows every 100 or so points, so there is less to render.
  2. Try using the ContinuousAction->False option (see documentation) (I see @Szabolcs had the same idea as I was typing.
  3. I was about to suggest MaxPlotPoints, but instead try the PerformanceGoal ->"Speed" option. (see documentation)
甜味超标? 2024-11-25 11:38:46

我还注意到 Mathematica 有时会花费太长时间来渲染图形。实际上,它必须是从 Mathematica Graphics 表达式到其他表示的某种转换步骤,该步骤需要很长时间,因为一旦渲染,调整图形大小(从而重新渲染)要快得多。对于许多示例来说,版本 6 之前的图形渲染速度更快(但也缺乏 6+ 版本所具有的许多功能)。

关于您可以做什么的一些想法:

  1. 使用 ListLinePlotMaxPlotPoints 选项在绘图之前减少数据。如果进行下采样,外观可能不会有什么不同。 Method 选项应选择下采样算法,但我找不到任何相关文档(有人吗?)

  2. Use ContinouslyAction -> Manipulate 中的 False 可阻止它在拖动滑块时实时重新计算所有内容。

I also noticed that occasionally Mathematica will take too long to render graphics. Actually it must be some translation step from a Mathematica Graphics expression to some other representation that takes long because once rendered, resizing (and thus re-rendering) the graphic is much faster. Pre-version-6 graphics rendering used to be faster for many examples (but also lacks a lot of functionality that 6+ have).

Some ideas about what you could do:

  1. Use the MaxPlotPoints option of ListLinePlot to reduce the data before plotting. It might not make a difference in looks if its downsampled. The Method option should choose the downsample algorithm, but I can't find any docs for it (anyone?)

  2. Use ContinuousAction -> False in Manipulate to stop it from recomputing everything in real time as you drag the sliders.

猫瑾少女 2024-11-25 11:38:46

Another idea here is using the Ramer–Douglas–Peucker algorithm to reduce the number of data points before plotting. This will likely preserve the shape of the data better. I don't know if you still need this so I won't provide an implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文