Mathematica produces fantastic-looking graphics, but it can be slow on large data sets. Here is an example for a (random) time series:
rv = RandomVariate[ExponentialDistribution[2], 10^5];
Plotting this takes quite some time:
t = AbsoluteTime[]; ListLinePlot[rv, PlotRange -> All]
AbsoluteTime[] - t (* Put this line into the NEXT cell, and evaluate both cells together*)
The option PerformanceGoal->"Speed" has no effect.
Turning off antialiasing makes it much faster (but if you increase the data size to 10^6 instead of 10^5, it is still VERY slow. A time series of 10^6 points is quite reasonable in my applications):
t = AbsoluteTime[];
Style[ListLinePlot[rv, PlotRange -> All], Antialiasing -> False]
AbsoluteTime[] - t (* This line in separate cell! *)
Reducing the number of MaxPlotPoints makes it much faster, but completely distorts the shape of the data:
t = AbsoluteTime[]; ListLinePlot[rv, PlotRange -> All, MaxPlotPoints -> 1000]
AbsoluteTime[] - t (* This line in separate cell! *)
Question: I am interested in tricks to show the data quickly without distorting the shape. I am showing here my own solution, which is quite a bit of a hack, but it works. Are there more elegant solutions?
My own solution:
(see also here for a simpler version of this)
Options[fastListPlot] = {plotPoints -> 1000, AspectRatio -> Full, PlotRange -> All, Options[ListLinePlot]} // Flatten
fastListPlot[data_, opts:OptionsPattern[]] :=
Module[{plotData=data, lengths, range = Automatic, points = OptionValue[plotPoints]},
While[Depth[plotData] <= 2, plotData= {plotData}];
lengths = Length/@plotData;
If[NumericQ[points],
plotData = Partition[#, Floor[Min[lengths]/points]]& /@ plotData;
plotData = Flatten[{Min /@ #, Max /@ #}\[Transpose]] & /@ plotData;
range = Max[lengths]
];
ListLinePlot[plotData, FilterRules[{opts, DataRange -> range,Options[fastListPlot]},Options[ListLinePlot]]
]
]
The trick is within the If statement: I partition the data into a number of blocks corresponding roughly to the resolution of my screen (usually 1000 or less, option plotPoints). Then I determine the Min and Max of each block, and draw a zig-zag line from min to max to min to max...
My solution, as presented, works for simple lists (i.e. of Depth 2), and also for lists containing more than 1 data set (Depth 3).
Examples:
fastListPlot[rv]
fastListPlot[rv, plotPoints -> All] (* The "normal" slow version *)
fastListPlot[{rv,rv/2}] (* more than 1 dataset *)
The following doesn't quite work correctly (problem with DataRange):
fastListPlot[{rv,Take[rv/2,10000]}, plotPoints -> All] (* original *)
fastListPlot[{rv,Take[rv/2,10000]}, plotPoints -> 1000]






TimingorAbsoluteTimingto time the execution of a command, instead of having to subtract time values manually. – David Zaslavsky Jan 18 '12 at 11:19Graphicsobject to render on screen?AbsoluteTimingmight cover that as well, since it measures wall time, not CPU time, though I forget when exactly it stops. (BTW, if rendering is the bottleneck, saving the plot to a rasterized image file can be a good strategy) – David Zaslavsky Jan 18 '12 at 12:17AbsoluteTiming[]doesn't cover rendering of the graphic. It only times how long it takes for the kernel to finish, and the rendering is done by the front end only after theGraphicsexpression has been sent to it. Generally, bothTimingandAbsoluteTimingmeasure the time it takes for the kernel to finish (not front end), but the former is CPU time while the latter is wall time. – Szabolcs Jan 18 '12 at 12:23Timingis CPU time, yes, butAbsoluteTimingdoes not say it is wall time at all, it just saysmeasures only the time involved in actually evaluating expr, not time involved in formatting the result.Only now I know this means wall time! When it says real time at the top, I thought it meant real time for the CPU as well. Wall time is more clear. So, I always wondered what is the difference. – Nasser Jan 18 '12 at 17:24