# Animating the steps of a Kohonen SOM in Mathematica [duplicate]

As the title suggest, I'm trying to make an animation of how a bunch of points into 2-D (and possibly 3-D space) evolves by each step of my program.

In order to do so I've data which contains the x and y position of every single point of the map at a given "time" t, which is defined by jumping over 20 elements of the list.

i.e. t=0 goes from row 1 to row 20, t=1 from row 21 to row 40, etc...

here's the file: Full Version: https://www.mediafire.com/?irgddwos6qn5kb1 Light Version: https://www.mediafire.com/?rdx66fsyzejonhx

and here's what i've written in order to obtain x and y positions of points at a given time:

    dati = Import["...\\KOHONEN SOM\\output.dat"]
{a, b} = Transpose[dati];
neuro = 20;
x = Array[h, neuro];
y = Array[j, neuro];
Table[x[[k]] = Table[a[[k + i*neuro*4]], {i, 0, 50000}], {k, 1, neuro}];
Table[y[[k]] = Table[b[[k + i*neuro*4]], {i, 0, 50000}], {k, 1, neuro}];
X = Array[l, 50000];
Y = Array[s, 50000];
Table[X[[l]] = Table[x[[j]][[l]], {j, 1, neuro}], {l, 1, 50000}];
Table[Y[[l]] = Table[y[[j]][[l]], {j, 1, neuro}], {l, 1, 50000}];


Note that the i*neuro*4 thing is in order to take a little less of all the data i have

I've also been able to make plots of each evolution step, as shown here:

 POW = Table[
ListPlot[Transpose[{X[[l]], Y[[l]]}], PlotRange -> All], {l, 1,
50000}];


This allows me to have the single frames of the animation, but yet, I haven't been able to combine them into an animation.

Moreover, I was looking for having the points connected by a line in the animation itself, so that, if I'd start increasing the numbers of neuro, it wouldn't be a mess to understand what's going on...

-

## marked as duplicate by Öskå, Michael E2, Yves Klett, ciao, RunnyKineJun 19 '14 at 4:34

Can't you come up with a short working example showing your issue? – Öskå Jun 18 '14 at 9:34
if you download my file and run that little program of mine, you'll see that i can produce a lot of images with points on them, in a 2-D space (since the output.dat contains 2 columns of x and y data). I'd like to put them into an animation, which shows the evolution of the points in the 2-D space, if possible, aving those dots connected by a line. At the moment i don't have an example, since all I'm doing with the animation stuff just doesn't work – Andrea Jun 18 '14 at 10:18
It's a 80MB file, if it's contains two columns of x and y data I'm sure you can reduce the number of rows to make it < 1MB. – Öskå Jun 18 '14 at 10:59
I can indeed: mediafire.com/?rdx66fsyzejonhx – Andrea Jun 18 '14 at 11:12

dati = Import["~/Downloads/output2.dat"];
{a, b} = Transpose[dati];
neuro = 20;
x = Array[h, neuro];
y = Array[j, neuro];
itLength = Floor[Length@a/(neuro*4)];
Table[x[[k]] = Table[a[[k + i*neuro*4]], {i, 0, itLength}], {k, 1, neuro}];
Table[y[[k]] = Table[b[[k + i*neuro*4]], {i, 0, itLength}], {k, 1, neuro}];
X = Array[l, itLength];
Y = Array[s, itLength];
Table[X[[l]] = Table[x[[j]][[l]], {j, 1, neuro}], {l, 1, itLength}];
Table[Y[[l]] = Table[y[[j]][[l]], {j, 1, neuro}], {l, 1, itLength}];
POW = Table[
ListLinePlot[Transpose[{X[[l]], Y[[l]]}], PlotRange -> {0, 20},
AxesOrigin -> {0, 0}, PlotStyle -> Hue[Rescale[l, {0, itLength}]]], {l, 1, itLength, 10}]


Then, all you have to do is to Export it as a GIF:

Export["~/animated.gif", POW, "DisplayDurations" -> .1]


-
that's what i was looking for, i only wish to know if ther's a way to have fixed axes – Andrea Jun 18 '14 at 14:19
@Andrea PlotRange -> {{0, 20}, {0, 20}} :) – Öskå Jun 18 '14 at 14:21
oh right, thanks a lot! :) – Andrea Jun 18 '14 at 15:03

Mathematica has lots of tools to handle exactly what you seem to want to do. (See What are the most common pitfalls awaiting new users? for some links and pointers.) Your code basically uses Table as a for-loop, which is not what it is designed for. For does that. But there are much more concise and clearer ways to achieve what you want. (Well, clearer once the basic idea of a couple of functions are known.)

There are three or four I'll use.

• Partition, which will partition your data into sets of neuro = 20 groups. Then your "time" index t can be used with datp[[t]]: datp[[1], datp[[2]], etc.

• Span (;;), which can be used to select a subrange from a list or array, including skipping so many elements each time.

• Map (/@), which can be used to apply a Function (ListLinePlot[#,...] & in the case below) to each element of a list.

Then your code can be rewritten like this:

dati = Import["~/Downloads/output.dat"];
neuro = 20;
datp = Partition[dati, neuro];
pow = ListLinePlot[#, PlotRange -> {{0, 20}, {0, 20}}] & /@ datp[[1 ;; All ;; 4]]


The keyword All is very convenient here. You don't even have to know how much data you have. (Many people use -1 instead of All. The -1 indicates the last element.) The 4 is how many elements to skip each time. For the full data set, you might want to start with a much larger value, like 400 or 2000 to get a quick overview.

Further tips:

It's more efficient to work with large amounts of data as packed arrays, if possible. Your imported data will not be packed, but it can be via:

dati = DeveloperToPackedArray @ Import["~/Downloads/output.dat"];


You can save it in a much more efficient form with DumpSave (with the semicolon to suppress printing dati).

DumpSave["file.mx", dati];


You can reload it (packed, if it was saved as a packed array) with Get:

Get["file.mx"]


Or you can save datp`, which might be more convenient.

-
well, thanks a lot, that's a lot of advices! and it looks like using them would have saved me a lot of time in my previous notebooks... thanks again! – Andrea Jun 19 '14 at 11:12
@Andrea You're welcome. :) – Michael E2 Jun 19 '14 at 14:04