forked from neozhaoliang/pywonderland
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lorenz.py
90 lines (64 loc) · 2.24 KB
/
lorenz.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# -*- coding: utf-8 -*-
"""
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Make 3D Animations of Lorenz Attractor with Matplotlib
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
code adapted from
"https://jakevdp.github.io/blog/2013/02/16/animating-the-lorentz-system-in-3d/"
"""
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
from scipy.integrate import odeint
from mpl_toolkits.mplot3d import Axes3D
# number of particles.
num_particles = 20
# constants for Lorenz system.
alpha = 10.0
beta = 8/3.0
gamma = 28.0
def derivative(point, t):
"""return the tangent direction at (x,y,z)."""
x, y, z = point
return [alpha * (y - x),
x * (gamma - z) - y,
x * y - beta * z]
fig = plt.figure(figsize=(6.4, 4.8), dpi=100)
ax = fig.add_axes([0, 0, 1, 1], projection='3d', xlim=(-25, 25),
ylim=(-35, 35), zlim=(5, 55), aspect=1)
ax.view_init(30, 0)
ax.axis('off')
lines = []
points = []
colors = plt.cm.gist_ncar(np.linspace(0, 1, num_particles))
for c in colors:
lines.extend(ax.plot([], [], '-', c=c))
points.extend(ax.plot([], [], 'o', c=c))
x0 = -15 + 30 * np.random.random((num_particles, 3))
t = np.linspace(0, 4, 1001)
x_t = np.array([odeint(derivative, point, t) for point in x0])
def init():
for line, point in zip(lines, points):
line.set_data([], [])
line.set_3d_properties([])
point.set_data([], [])
point.set_3d_properties([])
return lines + points
def animate(i):
i = 2*i % x_t.shape[1] # accelarate the animation.
for line, point, x_j in zip(lines, points, x_t):
x, y, z = x_j[:i].T
line.set_data(x, y)
line.set_3d_properties(z)
# note that plot() receives a list parameter so we have
# to write x[-1:] instead of x[-1]!
point.set_data(x[-1:], y[-1:])
point.set_3d_properties(z[-1:])
ax.view_init(30, 0.3*i)
fig.canvas.draw()
return lines + points
anim = FuncAnimation(fig, animate, init_func=init, interval=5,
frames=500, blit=True)
#fig.show()
anim.save('lorenz.webm', writer='ffmpeg', fps=30, dpi=100,
bitrate=1000, codec='libvpx', extra_args=['-crf', '10'])