0
$\begingroup$

I have a scatterplot composed of about 1M points, which I would like to plot in succession as the axis scale increases. Here is the code, where Coordinates[n_] gives the first n {x,y} values. The problem I run into is that the notebook never finishes evaluating... if I try to use "Animate," I run into the problem that the exported video shows "aborted" for large n. Thanks for any advice!!

Export["Animation.avi", 
 ListAnimate[
  Table[ListPlot[Coordinates[n], 
    PlotRange -> {{-1.1*Max[Abs[Coordinates[n]]], 
       1.1*Max[Abs[Coordinates[n]]]}, {-1.1*Max[Abs[Coordinates[n]]], 
       1.1*Max[Abs[Coordinates[n]]]}}, PlotMarkers -> {Automatic, 1}, 
    PlotStyle -> White, Background -> Black, 
    Frame -> {{False, False}, {False, False}}, Axes -> {False, False},
     AspectRatio -> Full, ImageSize -> {800, 800}], {n, 1, 1000001, 
    100}], 60]]
$\endgroup$
  • $\begingroup$ Is Coordinates a list of 1 million points? And are you trying to plot the first point in that list, then plot the first 101 points, then 201 points, then 301... etc? If so, you should be using Coordinates[[1;;n]] to tell it to take only the first n points. Also, try changing n in steps of 500000 at first. This will only give you 3 graphs but should run faster and give you an idea if it's behaving the way you wanted. After that you can start decreasing the step size. Keep in mind that generating 10000 graphs will take a very long time and the output file will probably be gigabytes. $\endgroup$ – MassDefect Feb 5 at 6:49
  • $\begingroup$ Yes, exactly. Thanks for the tip on Coordinates[[1;;n]]. Hmm, is there any way to dynamically plot the points in order, instead of generating 10000 separate graphs? I could increase the step size somewhat, but ideally am looking for a video file of about 30 minutes. Thanks! $\endgroup$ – user413587 Feb 5 at 17:36
0
$\begingroup$

I think I misunderstood your use of Coordinates. The way you use it as a function is fine, but I think it would be faster to store them as a list once rather than recalculating it each time.

coords = Coordinates[1000001];

And then access the coordinates using the coords[[1;;n]] notation.

If you're looking to output that many frames, one of the ways I can think of to speed things up is to either use Epilog to draw the individual points or to use Graphics. I'm not entirely sure why, but it's much faster. Also, I included axes on my graphs, but you can easily suppress those with the Axes -> False option.

The fastest case is where we can preset the axes to be the full range of the data from the beginning. That way we don't have to recalculate the axes each time. Based on your question, I think that you probably do want to see the axes change each time, but I'll include this here anyway.

dat = Table[{x, Sin[x/10000.] + Sin[4 x/10000.]}, {x, 10^6}];
initialplot = ListPlot[
  {dat[[1]]},
  PlotStyle -> Black,
  PlotRange -> {{0, Max[dat[[All, 1]]]}, MinMax[dat[[All, 2]]]}
 ]
AbsoluteTiming[
 anim = Table[
    Show[
     initialplot,
     Epilog -> Point@dat[[1 ;; n]]],
    {n, 1, Length[dat], 100000}];]
anim[[2]]

This takes 0.28 seconds on my machine meaning that 10000 frames should take about 280 seconds or just under 5 minutes. Of course, the export process will incur a substantial time penalty on top of that. You can see the result below. Because the axes a pre-set, the data only takes up part of the full range.

Second frame of the animation using the fastest code.

AbsoluteTiming[
 anim3 = Table[
    ListPlot[
     {dat[[1]]},
     PlotRange -> {{0, n}, MinMax[dat[[;; n, 2]]]},
     Epilog -> {
       Point@dat[[1 ;; n]]
       }],
    {n, 1, Length[dat], 100000}];]
anim3[[2]]

Second frame of the animation using slightly slower code.

I think this code produces something closer to what you're looking for, but it takes about 2.34 seconds to run, meaning 10000 frames would be about 40 minutes (not including export). For comparison, 10 traditional ListPlots with the range changing each time takes about 54 seconds so the 10000 frames would take about 15 hours (not including export).

The last way that I tried was just with Graphics alone, and it seemed to run pretty quickly. I think you still have access to most of the normal features of a ListPlot, but the axes range changes with each new data point and it runs faster.

AbsoluteTiming[
 ganim = Table[
    Graphics[{
      Point@dat[[1 ;; n]]
      }, 
      AspectRatio -> 1],
{n, 1, 1000000, 100000}];]
ganim[[2]]

These 10 plots are produced in 0.27 seconds, and the second frame is:

Second frame of animation using Graphics only.

I think this one might be the best option for you, though it's possible that you may come across some strange behaviour depending on what data you're plotting since it uses Graphics rather than ListPlot.

As for the Export, I don't think that ListAnimate is necessary. I think the following would work:

Export["Animation.avi", ganim]

Also, I would recommend trying this on 100 to 1000 frames first to make sure that it works as expected.

$\endgroup$
  • $\begingroup$ This is amazingly helpful, thank you so much!! $\endgroup$ – user413587 Feb 6 at 19:32
  • $\begingroup$ @user413587 No problem! $\endgroup$ – MassDefect Feb 6 at 19:45

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.