1"""
2================
3Lorenz Attractor
4================
5
6This is an example of plotting Edward Lorenz's 1963 `"Deterministic Nonperiodic
7Flow"`_ in a 3-dimensional space using mplot3d.
8
9.. _"Deterministic Nonperiodic Flow":
10   https://journals.ametsoc.org/jas/article/20/2/130/16956/Deterministic-Nonperiodic-Flow
11
12.. note::
13   Because this is a simple non-linear ODE, it would be more easily done using
14   SciPy's ODE solver, but this approach depends only upon NumPy.
15"""
16
17import numpy as np
18import matplotlib.pyplot as plt
19
20
21def lorenz(x, y, z, s=10, r=28, b=2.667):
22    """
23    Given:
24       x, y, z: a point of interest in three dimensional space
25       s, r, b: parameters defining the lorenz attractor
26    Returns:
27       x_dot, y_dot, z_dot: values of the lorenz attractor's partial
28           derivatives at the point x, y, z
29    """
30    x_dot = s*(y - x)
31    y_dot = r*x - y - x*z
32    z_dot = x*y - b*z
33    return x_dot, y_dot, z_dot
34
35
36dt = 0.01
37num_steps = 10000
38
39# Need one more for the initial values
40xs = np.empty(num_steps + 1)
41ys = np.empty(num_steps + 1)
42zs = np.empty(num_steps + 1)
43
44# Set initial values
45xs[0], ys[0], zs[0] = (0., 1., 1.05)
46
47# Step through "time", calculating the partial derivatives at the current point
48# and using them to estimate the next point
49for i in range(num_steps):
50    x_dot, y_dot, z_dot = lorenz(xs[i], ys[i], zs[i])
51    xs[i + 1] = xs[i] + (x_dot * dt)
52    ys[i + 1] = ys[i] + (y_dot * dt)
53    zs[i + 1] = zs[i] + (z_dot * dt)
54
55
56# Plot
57ax = plt.figure().add_subplot(projection='3d')
58
59ax.plot(xs, ys, zs, lw=0.5)
60ax.set_xlabel("X Axis")
61ax.set_ylabel("Y Axis")
62ax.set_zlabel("Z Axis")
63ax.set_title("Lorenz Attractor")
64
65plt.show()
66