Suppose you have 5 arrays (normalized by the number of arrays - in this case 5):

arrayList = Table[RandomChoice[Developer`ToPackedArray@{-1, 1}, {100, 100}]/5,{5}]

Your new array:

arraySum = Total[arrayList];

will have various possible values between: $-1$ and $1$. You then can visualize this new array using ArrayPlot:

ArrayPlot[arraySum, ColorFunction -> ColorData["SunsetColors"], ImageSize-> Medium]

enter image description here

What I want to do is make an animation which allows you to see how an array progresses from one to the other, a sort of visualization of the progression starting from arrayList[[1]] to arrayList[[-1]].

This is rather straight forward as you can do an accumulative sum of the arrays:

accumArrays = Accumulate[arrList]

and then generate a list of the corresponding array plots:

arrPlotList = Table[ 
                  ArrayPlot[accumArrays[[i]], ColorFunction -> ColorData["SunsetColors"], 
                            ImageSize-> Medium],

As you see with this animation:

enter image description here

However, I want to create a smoother transition between each frame - which requires inserting more frames of course. Here is my code which achieves this - and where issues with RAM starting coming into play.

makeSmoothAnimation[allarr_, fps_, dur_] := Module[{nSubArr, bitSize,bitArr,imgList},
    nSubArr = Round[(fps*dur)/Length[allarr]];
    bitSize = (1/Length[allarr])/nSubArr;
    bitArr = Accumulate[Flatten[Table[Table[allarr[[j]]*bitSize, {nSubArr}],{j, Length[allarr]}], 1]];
    Print["Made Imdata"];
    imgList = Table[
               ArrayPlot[bitArr[[i]], ColorFunction -> ColorData["SunsetColors"], ImageSize -> Medium]
              , {i, 1, Length[bitArr]}];

Export["movie001.png",imgList,"VideoFrames"] creates a .png image for each image in imgList. I then use Blender to generate a .avi or which ever extension.

Here I create the animation using 20 fps and a duration of 5s.

makeSmoothAnimation[arrayList_, 20_, 5_]

Here is the result of the above - as you see nice and smooth.enter image description here

The issue comes in with the following. I have 13 of these arrays, and all the arrays are 2000 x 2000. I want to process them at 30fps for a duration of 13s as start, and ideally at 60fps for a duration of 26s. However I cannot even achieve the former. I have 16Gb of RAM, and it always runs out. I appreciate that these are massive arrays and well, sometimes it's tough luck. But I don't think this is the case. How could I improve - or even change the above - makeSmoothAnimation function such that I don't run out of memory?

  • $\begingroup$ Why not export the frames one by one instead of keeping all the frames in memory? $\endgroup$ – C. E. Jun 9 '17 at 11:28
  • $\begingroup$ If I'm not mistaken I tried that, by converting each frame into a .png and exporting. It however it was giving me errors. Thus I found this solution of using the "VideoFrames" option, which seemed quite neat. I haven't had a proper go fixing that error, as I thought the errors were a result of memory issues. I will look into it again. $\endgroup$ – Luca Pontiggia Jun 9 '17 at 11:39
  • $\begingroup$ @C.E From trying what you suggested, I found it actually works, however. I still run out of memory. What the issue here is the Accumulate function, this is what it taking all the memory. I would need to first have the accumulated list before exporting each frame. I guess what I could do is write my own accumulate function which exports the the new accumulated frame after every iteration. $\endgroup$ – Luca Pontiggia Jun 9 '17 at 11:53
  • $\begingroup$ Yes, I would say that is what you have to do. Accumulate builds up a list of results. You only want the least amount of data necessary to render the current frame. $\endgroup$ – C. E. Jun 9 '17 at 19:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.