Skip to content

Commit 599e2bd

Browse files
committed
n-body: show a possible animation
1 parent 15a3791 commit 599e2bd

File tree

4 files changed

+717
-24
lines changed

4 files changed

+717
-24
lines changed

notebooks/numpy-tps/n-body/.teacher/README-n-body-corrige-nb.md

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def init_problem(N):
106106
107107
masses, positions, speeds = init_problem(10)
108108
109-
# et ceci devrait afficker OK
109+
# et ceci devrait afficher OK
110110
try:
111111
masses.shape == (10,) and positions.shape == speeds.shape == (2, 10)
112112
print("OK")
@@ -194,9 +194,9 @@ masses, positions, speeds = init3()
194194
f = forces(masses, positions)
195195
196196
# should be true
197-
np.all(np.isclose(f, np.array([
198-
[ 0. , -0.12257258, 0.12257258],
199-
[ 0. , -0.02451452, 0.02451452]])))
197+
# np.all(np.isclose(f, np.array([
198+
# [ 0. , -0.12257258, 0.12257258],
199+
# [ 0. , -0.02451452, 0.02451452]])))
200200
```
201201

202202
## le simulateur
@@ -261,12 +261,13 @@ except Exception as exc:
261261
```{code-cell} ipython3
262262
# pour tester: should be true
263263
264-
positions1 = s[1]
264+
# first step
265+
# positions1 = s[1]
265266
266-
np.all(np.isclose(positions1, np.array([
267-
[ 0. , 4.89877427, -4.89877427],
268-
[ 0. , 0.99975485, -0.99975485]
269-
])))
267+
# np.all(np.isclose(positions1, np.array([
268+
# [ 0. , 4.89877427, -4.89877427],
269+
# [ 0. , 0.99975485, -0.99975485]
270+
# ])))
270271
```
271272

272273
## dessiner
@@ -365,10 +366,12 @@ pour commencer et tester, on se met dans l'état initial reproductible
365366
steps = 100
366367
367368
masses, positions, speeds = init3()
368-
s = simulate(masses, positions, speeds, nb_steps=steps)
369-
draw(s, masses, colors3);
369+
simulation3 = simulate(masses, positions, speeds, nb_steps=steps)
370+
draw(simulation3, masses, colors3);
370371
371372
plt.savefig("init3.png")
373+
np.savetxt("simulation3.txt", simulation3.reshape(-1))
374+
print(simulation3.shape)
372375
```
373376

374377
et avec ces données vous devriez obtenir plus ou moins une sortie de ce genre
@@ -416,7 +419,7 @@ modifiez votre code pour passer à une simulation en 3D
416419

417420
### option 2: un rendu plus interactif
418421

419-
le rendu sous forme de multiple scatter plots donne une idée du résultat mais c'est très améliorable
422+
le rendu sous forme de multiples scatter plots donne une idée du résultat mais c'est très améliorable
420423
voyez un peu si vous arrivez à produire un outil un peu plus convivial pour explorer les résultats de manière interactive; avec genre
421424

422425
- une animation qui affiche les points au fur et à mesure du temps
@@ -425,4 +428,48 @@ voyez un peu si vous arrivez à produire un outil un peu plus convivial pour exp
425428
- et si vous avez un code 3d, la possibilité de changer le point de vue de la caméra sur le monde
426429
- etc etc...
427430

428-
pas obligé de rester dans Jupyter Lab hein, il y a plein de technos rigolotes qui savent se décliner sur le web, vous avez l'embarras du choix...
431+
voici une possibilité avec matplotlib; mais cela dit ne vous sentez pas obligé de rester dans Jupyter Lab ou matplotlib, il y a plein de technos rigolotes qui savent se décliner sur le web, vous avez l'embarras du choix...
432+
433+
```{code-cell} ipython3
434+
:tags: [prune-remove-input]
435+
436+
# prune-remove-input
437+
438+
# credit: Damien Corral
439+
# with good old matplotlib FuncAnimation
440+
441+
from matplotlib.animation import FuncAnimation
442+
from IPython.display import HTML
443+
444+
def animate(simulation, masses, colors=None, scale=5., interval=50):
445+
nb_steps, _, N = simulation.shape
446+
colors = (colors if colors is not None
447+
else np.random.uniform(0.3, 1., size=(N, 3)))
448+
449+
fig, ax = plt.subplots()
450+
ax.set_title(f"we have {N} bodies over {nb_steps} steps")
451+
452+
ax.set_xlim(simulation[:, 0].min() - 1, simulation[:, 0].max() + 1)
453+
ax.set_ylim(simulation[:, 1].min() - 1, simulation[:, 1].max() + 1)
454+
455+
scat = ax.scatter(np.zeros(N), np.zeros(N), c=colors, s=(masses*scale)**2)
456+
457+
def init():
458+
scat.set_offsets(np.zeros((nb_steps, N)))
459+
return scat
460+
461+
def update(step):
462+
x, y = simulation[step]
463+
scat.set_offsets(np.c_[x, y])
464+
return scat
465+
466+
ani = FuncAnimation(fig, update, frames=nb_steps,
467+
init_func=init, blit=True, interval=interval)
468+
plt.close()
469+
return ani
470+
471+
472+
simulation3 = np.loadtxt("data/simulation3.txt").reshape((100, 2, 3))
473+
animation = animate(simulation3, masses, colors=colors3)
474+
HTML(animation.to_jshtml())
475+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../data/

notebooks/numpy-tps/n-body/README-n-body-nb.md

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def init_problem(N):
8787
8888
masses, positions, speeds = init_problem(10)
8989
90-
# et ceci devrait afficker OK
90+
# et ceci devrait afficher OK
9191
try:
9292
masses.shape == (10,) and positions.shape == speeds.shape == (2, 10)
9393
print("OK")
@@ -152,9 +152,9 @@ masses, positions, speeds = init3()
152152
f = forces(masses, positions)
153153
154154
# should be true
155-
np.all(np.isclose(f, np.array([
156-
[ 0. , -0.12257258, 0.12257258],
157-
[ 0. , -0.02451452, 0.02451452]])))
155+
# np.all(np.isclose(f, np.array([
156+
# [ 0. , -0.12257258, 0.12257258],
157+
# [ 0. , -0.02451452, 0.02451452]])))
158158
```
159159

160160
## le simulateur
@@ -192,12 +192,13 @@ except Exception as exc:
192192
```{code-cell} ipython3
193193
# pour tester: should be true
194194
195-
positions1 = s[1]
195+
# first step
196+
# positions1 = s[1]
196197
197-
np.all(np.isclose(positions1, np.array([
198-
[ 0. , 4.89877427, -4.89877427],
199-
[ 0. , 0.99975485, -0.99975485]
200-
])))
198+
# np.all(np.isclose(positions1, np.array([
199+
# [ 0. , 4.89877427, -4.89877427],
200+
# [ 0. , 0.99975485, -0.99975485]
201+
# ])))
201202
```
202203

203204
## dessiner
@@ -299,7 +300,7 @@ modifiez votre code pour passer à une simulation en 3D
299300

300301
### option 2: un rendu plus interactif
301302

302-
le rendu sous forme de multiple scatter plots donne une idée du résultat mais c'est très améliorable
303+
le rendu sous forme de multiples scatter plots donne une idée du résultat mais c'est très améliorable
303304
voyez un peu si vous arrivez à produire un outil un peu plus convivial pour explorer les résultats de manière interactive; avec genre
304305

305306
- une animation qui affiche les points au fur et à mesure du temps
@@ -308,4 +309,48 @@ voyez un peu si vous arrivez à produire un outil un peu plus convivial pour exp
308309
- et si vous avez un code 3d, la possibilité de changer le point de vue de la caméra sur le monde
309310
- etc etc...
310311

311-
pas obligé de rester dans Jupyter Lab hein, il y a plein de technos rigolotes qui savent se décliner sur le web, vous avez l'embarras du choix...
312+
voici une possibilité avec matplotlib; mais cela dit ne vous sentez pas obligé de rester dans Jupyter Lab ou matplotlib, il y a plein de technos rigolotes qui savent se décliner sur le web, vous avez l'embarras du choix...
313+
314+
```{code-cell} ipython3
315+
:tags: [prune-remove-input, remove-input]
316+
317+
# prune-remove-input
318+
319+
# credit: Damien Corral
320+
# with good old matplotlib FuncAnimation
321+
322+
from matplotlib.animation import FuncAnimation
323+
from IPython.display import HTML
324+
325+
def animate(simulation, masses, colors=None, scale=5., interval=50):
326+
nb_steps, _, N = simulation.shape
327+
colors = (colors if colors is not None
328+
else np.random.uniform(0.3, 1., size=(N, 3)))
329+
330+
fig, ax = plt.subplots()
331+
ax.set_title(f"we have {N} bodies over {nb_steps} steps")
332+
333+
ax.set_xlim(simulation[:, 0].min() - 1, simulation[:, 0].max() + 1)
334+
ax.set_ylim(simulation[:, 1].min() - 1, simulation[:, 1].max() + 1)
335+
336+
scat = ax.scatter(np.zeros(N), np.zeros(N), c=colors, s=(masses*scale)**2)
337+
338+
def init():
339+
scat.set_offsets(np.zeros((nb_steps, N)))
340+
return scat
341+
342+
def update(step):
343+
x, y = simulation[step]
344+
scat.set_offsets(np.c_[x, y])
345+
return scat
346+
347+
ani = FuncAnimation(fig, update, frames=nb_steps,
348+
init_func=init, blit=True, interval=interval)
349+
plt.close()
350+
return ani
351+
352+
353+
simulation3 = np.loadtxt("data/simulation3.txt").reshape((100, 2, 3))
354+
animation = animate(simulation3, masses, colors=colors3)
355+
HTML(animation.to_jshtml())
356+
```

0 commit comments

Comments
 (0)