Animating the Lorenz System in 3D

8
Pythonic Perambulations (https://jakevdp.github.io/) Musings and ramblings through the world of Python and beyond Atom (/atom.xml) Search Navigate… Archives (/archives.html) Home Page (http://www.astro.washington.edu/users/vanderplas) Animating the Lorenz System in 3D Feb 16, 2013 One of the things I really enjoy about Python is how easy it makes it to solve interesting problems and visualize those solutions in a compelling way. I've done several posts on creating animations using matplotlib's relatively new animation toolkit (http://matplotlib.sourceforge.net/api/animation_api.html): (some examples are a chaotic double pendulum (/blog/2012/08/18/matplotlibanimationtutorial/), the collisions of particles in a box (/blog/2012/08/18/matplotlibanimationtutorial/), the timeevolution of a quantummechanical wavefunction (/blog/2012/09/05/quantumpython/), and even a scene from the classic video game, Super Mario Bros. (/blog/2013/01/13/hackingsupermariobroswithpython/)). Recently, a reader commented (/blog/2012/08/18/matplotlibanimationtutorial/#comment799781196) asking whether I might do a 3D animation example. Matplotlib has a decent 3D toolkit called mplot3D (http://matplotlib.org/mpl_toolkits/mplot3d/index.html), and though I haven't previously seen it used in conjunction with the animation tools, there's nothing fundamental that prevents it. At the commenter's suggestion, I decided to try this out with a simple example of a chaotic system: the Lorenz equations. Solving the Lorenz System The Lorenz Equations (http://en.wikipedia.org/wiki/Lorenz_system) are a system of three coupled, firstorder, nonlinear differential equations which describe the trajectory of a particle through time. The system was originally derived by Lorenz as a model of atmospheric convection, but the deceptive simplicity of the equations have made them an oftenused example in fields beyond atmospheric physics. The equations describe the evolution of the spatial variables , , and , given the governing parameters , , and , through the specification of the timederivatives of the spatial variables: The resulting dynamics are entirely deterministic giving a starting point and a time interval . Though it looks straightforward, for certain choices of the parameters , the trajectories become chaotic, and the resulting trajectories display some surprising properties.

description

python learning

Transcript of Animating the Lorenz System in 3D

Page 1: Animating the Lorenz System in 3D

Pythonic Perambulations(https://jakevdp.github.io/)Musings and ramblings through the world ofPython and beyond

Atom (/atom.xml)

Search

Navigate…

Archives (/archives.html)Home Page (http://www.astro.washington.edu/users/vanderplas)

Animating the Lorenz System in 3DFeb 16, 2013

One of the things I really enjoy about Python is how easy it makes it to solve interesting problems and visualizethose solutions in a compelling way. I've done several posts on creating animations using matplotlib's relatively newanimation toolkit (http://matplotlib.sourceforge.net/api/animation_api.html): (some examples are a chaotic doublependulum (/blog/2012/08/18/matplotlib­animation­tutorial/), the collisions of particles in a box(/blog/2012/08/18/matplotlib­animation­tutorial/), the time­evolution of a quantum­mechanical wavefunction(/blog/2012/09/05/quantum­python/), and even a scene from the classic video game, Super Mario Bros.(/blog/2013/01/13/hacking­super­mario­bros­with­python/)).Recently, a reader commented (/blog/2012/08/18/matplotlib­animation­tutorial/#comment­799781196) asking whetherI might do a 3D animation example. Matplotlib has a decent 3D toolkit called mplot3D(http://matplotlib.org/mpl_toolkits/mplot3d/index.html), and though I haven't previously seen it used in conjunctionwith the animation tools, there's nothing fundamental that prevents it.At the commenter's suggestion, I decided to try this out with a simple example of a chaotic system: the Lorenzequations.

Solving the Lorenz SystemThe Lorenz Equations (http://en.wikipedia.org/wiki/Lorenz_system) are a system of three coupled, first­order,nonlinear differential equations which describe the trajectory of a particle through time. The system was originallyderived by Lorenz as a model of atmospheric convection, but the deceptive simplicity of the equations have madethem an often­used example in fields beyond atmospheric physics.The equations describe the evolution of the spatial variables , , and , given the governing parameters , , and ,through the specification of the time­derivatives of the spatial variables:The resulting dynamics are entirely deterministic giving a starting point and a time interval . Though it looksstraightforward, for certain choices of the parameters , the trajectories become chaotic, and the resulting trajectoriesdisplay some surprising properties.

Page 2: Animating the Lorenz System in 3D

Though no general analytic solution exists for this system, the solutions can be computed numerically. Pythonmakes this sort of problem very easy to solve: one can simply use Scipy's interface to ODEPACK(https://computation.llnl.gov/casc/odepack/odepack_home.html), an optimized Fortran package for solving ordinarydifferential equations. Here's how the problem can be set up:

import numpy as np

from scipy import integrate

# Note: t0 is required for the odeint function, though it's not used here.

def lorentz_deriv((x, y, z), t0, sigma=10., beta=8./3, rho=28.0):

"""Compute the time‐derivative of a Lorenz system."""

return [sigma * (y ‐ x), x * (rho ‐ z) ‐ y, x * y ‐ beta * z]

x0 = [1, 1, 1] # starting vector

t = np.linspace(0, 3, 1000) # one thousand time steps

x_t = integrate.odeint(lorentz_deriv, x0, t)

That's all there is to it!

Visualizing the resultsNow that we've computed these results, we can use matplotlib's animation and 3D plotting toolkits to visualize thetrajectories of several particles. Because I've described the animation tools in­depth in a previous post(/blog/2012/08/18/matplotlib­animation­tutorial/), I will skip that discussion here and jump straight into the code:

Lorenz System lorentz_animation.py download (/downloads/code/lorentz_animation.py)

import numpy as np

from scipy import integrate

from matplotlib import pyplot as plt

from mpl_toolkits.mplot3d import Axes3D

from matplotlib.colors import cnames

from matplotlib import animation

N_trajectories = 20

def lorentz_deriv((x, y, z), t0, sigma=10., beta=8./3, rho=28.0):

"""Compute the time‐derivative of a Lorentz system."""

return [sigma * (y ‐ x), x * (rho ‐ z) ‐ y, x * y ‐ beta * z]

# Choose random starting points, uniformly distributed from ‐15 to 15

np.random.seed(1)

x0 = ‐15 + 30 * np.random.random((N_trajectories, 3))

# Solve for the trajectories

t = np.linspace(0, 4, 1000)

Page 3: Animating the Lorenz System in 3D

x_t = np.asarray([integrate.odeint(lorentz_deriv, x0i, t)

for x0i in x0])

# Set up figure & 3D axis for animation

fig = plt.figure()

ax = fig.add_axes([0, 0, 1, 1], projection='3d')

ax.axis('off')

# choose a different color for each trajectory

colors = plt.cm.jet(np.linspace(0, 1, N_trajectories))

# set up lines and points

lines = sum([ax.plot([], [], [], '‐', c=c)

for c in colors], [])

pts = sum([ax.plot([], [], [], 'o', c=c)

for c in colors], [])

# prepare the axes limits

ax.set_xlim((‐25, 25))

ax.set_ylim((‐35, 35))

ax.set_zlim((5, 55))

# set point‐of‐view: specified by (altitude degrees, azimuth degrees)

ax.view_init(30, 0)

# initialization function: plot the background of each frame

def init():

for line, pt in zip(lines, pts):

line.set_data([], [])

line.set_3d_properties([])

pt.set_data([], [])

pt.set_3d_properties([])

return lines + pts

# animation function. This will be called sequentially with the frame number

def animate(i):

# we'll step two time‐steps per frame. This leads to nice results.

i = (2 * i) % x_t.shape[1]

for line, pt, xi in zip(lines, pts, x_t):

x, y, z = xi[:i].T

line.set_data(x, y)

line.set_3d_properties(z)

pt.set_data(x[‐1:], y[‐1:])

pt.set_3d_properties(z[‐1:])

Page 4: Animating the Lorenz System in 3D

ax.view_init(30, 0.3 * i)

fig.canvas.draw()

return lines + pts

# instantiate the animator.

anim = animation.FuncAnimation(fig, animate, init_func=init,

frames=500, interval=30, blit=True)

# Save as mp4. This requires mplayer or ffmpeg to be installed

#anim.save('lorentz_attractor.mp4', fps=15, extra_args=['‐vcodec', 'libx264'])

plt.show()

The resulting animation looks something like this:

Notice that there are two locations in the space that seem to draw­in all paths: these are the so­called "Lorenzattractors", and have some interesting properties which you can read about elsewhere. The qualitativecharacteristics of these Lorenz attractors vary in somewhat surprising ways as the parameters are changed. If youare so inclined, you may wish to download the above code and play with these values to see what the results looklike.I hope that this brief exercise has shown you the power and flexibility of Python for understanding and visualizing alarge array of problems, and perhaps given you the inspiration to explore similar problems.Happy coding!

Posted by Jake Vanderplas Feb 16, 2013Tweet 6 20

Comments16 Comments Pythonic Perambulations Login

Sort by Best Share ⤤ Favorite

0:00

Page 5: Animating the Lorenz System in 3D

Join the discussion…

• Reply •

Ben Root • 2 years agoIt is Lorenz, not lorentz

1

• Reply •

jakevdp • 2 years agoMod > Ben Root

Thanks ­ fixed that in all but the URL

• Reply •

Gael Varoquaux • 2 years agoHey Jake,

Have you ever played with the Mayavi interactive examples of the Lorentz system:http://docs.enthought.com/maya...andhttp://docs.enthought.com/maya...

I my opinion, what's really real with the second one, which is slightly more complex, is that youcan change parameters interactively and watch the system evolve.

1

• Reply •

jakevdp • 2 years agoMod > Gael Varoquaux

Hey Gael,Thanks for the links! Mayavi seems to have some pretty slick 3D tools! Maybe I'll spenda little more time playing around with that.

• Reply •

Tim Burton • 6 months agogreat animation...but when I tried to run it locally in IPython (with python 3.4) it erred out online 14 "invalid syntax" ???

eldad­a • 9 months agoThis is a fantastic tutorial (like many others I found in this blog)!I just merged this demo another one of yours (http://jakevdp.github.io/blog/... ) ­ this is bothbeautiful and fun as well as very useful!Many thanx!

One suggestion for the code ­

The lines:# set up lines and pointslines = sum([ax.plot([], [], [], '­', c=c) for c in colors], [])pts = sum([ax.plot([], [], [], 'o', c=c) for c in colors], [])

Share ›

Share ›

Share ›

Share ›

Share ›

Page 6: Animating the Lorenz System in 3D

• Reply •

Assume the `sum` function is not overloaded, which is often not the case in scientificprogramming with python (e.g. %pylab). An alternative code which does not rely on the `sum`function:lines = [l for c in colors for l in ax.plot([], [], [], '­', c=c)]pts = [pt for c in colors for pt in ax.plot([], [], [], 'o', c=c)]

• Reply •

jakevdp • 9 months agoMod > eldad­a

Thanks! The ``sum`` overloading is one of the many reasons that the IPython team isdeprecating %pylab in favor of %matplotlib, which doesn't do any silent overwriting ofbuilt­in functions. I'd recommend using the latter in the future.

• Reply •

David P. Sanders • a year ago

see more

−This is just amazingly beautiful! Probably the best animation out there of this stunning object!

Let me comment on the mathematics:You say that there are "two locations in the space that seem to draw in all paths". In youranimation it indeed seems that these two locations are in the center of some circle­like regions.

There are indeed two special points at the centers of those regions, but they are *unstable*fixed points, and hence are repellers, not attractors! Once a trajectory spends enough time nearone of those points, it will be ejected in a perpendicular direction and wind around the two"lobes".To see this, it's probably easier to run a single trajectory for more time. To *prove* it, of course,is a different story (and actually very difficult ­­ it was done in 2002 by Warwick Tucker).

In fact, each of those fixed points is (if I remember correctly) a so­called "saddle­­focus"."Focus" means that there is a two­dimensional object like a plane (the so­called "stablemanifold") where the trajectory approaches the fixed point asymptotically in a spiral; this iswhat you are seeing in the simulation. However, perpendicular to this planar­like object is aone­dimensional curve (the "unstable manifold"), along which point which were initially closeto the fixed point move away. Thus over all, *any* initial point which is not *exactly* on the

David P. Sanders • a year ago> David P. Sanders

OK, I was wrong. The two points at the centres of the "wings" (or "lobes", as I called them) in fact have an*incoming* one­dimensional stable direction, and an *unstable* two­dimensionalsubspace (for the linearised system) and hence a two­dimensional unstable manifold.However, they are "only slightly unstable", which is why a trajectory spends a long timewinding around them before it escapes. Apologies for the confusion!

I did the analytical stability calculations with sympy. When I finally get round tolearning to use some blogging software, I'll post it!

Share ›

Share ›

Share ›

Page 7: Animating the Lorenz System in 3D

XKCD Plots in Matplotlib: Going the Whole Numba vs. Cython: Take 2ALSO ON PYTHONIC PERAMBULATIONS

• Reply •

• Reply •

jakevdp • a year agoMod > David P. Sanders

Thanks for the info! I must admit I haven't looked closely at the theory behindthis... it's good to have my claims double­checked :)

• Reply •

tjc • 2 years agoWhoops. Sorry. My bad. was running in a pylab context. 'sum' works.

• Reply •

tjc • 2 years agoHi Jake,

I was a bit perplexed by the 'sum' on lines 35 and 37. Crashes as is, for me. Did you mean:

# set up lines and pointslines = [ax.plot([], [], [], '­', c=c)[0]for c in colors]pts = [ax.plot([], [], [], 'o', c=c)[0]for c in colors]

Thanks for your posts.

• Reply •

uriel_sandoval • a year ago> tjc

Probably you are using a notebook with pylab inline, and that calls you the np.sumfunction instead of the buit­in python sum.

• Reply •

Cam DP • 2 years agoVery pretty. Thanks for sharing!

• Reply •

Lywx • 2 years agoThat is a very high quality demostration of matplotlib in 3D.

• Reply •

Emi • 2 years agoWonderful!!!! The students can now see the chaotic evolution of this system, and what sensitivedependence on initial conditions means.

WHAT'S THIS?

Share ›

Share ›

Share ›

Share ›

Share ›

Share ›

Share ›

Share ›

Page 8: Animating the Lorenz System in 3D

XKCD Plots in Matplotlib: Going the WholeWay14 comments • a year ago

Jason K. Moore — Firefox 22 still doesn'tsupport H264 codec on Linux or Max (I think)so your animation doesn't show in thosebrowsers. If you …

Numba vs. Cython: Take 249 comments • a year ago

Sturla Molden — Some things to rememberwhen you use Fortran and f2py:1. Always pass aFortran­ordered array, or f2py will make atemporary copy. …

Embedding Matplotlib Animations inIPython Notebooks20 comments • 2 years ago

Jessica Hamrick — Thanks for this greattutorial!In case you or anyone else runs acrossthis issue ­­ the videos that were being createdby anim.save …

How Bad Is Your Colormap?5 comments • a month ago

michaelaye — Actively discussed here:https://github.com/matplotlib/...

Subscribe Add Disqus to your sited Privacy

Recent PostsThe Hipster Effect: An IPython Interactive Exploration (https://jakevdp.github.io/blog/2014/11/11/the­hipster­effect­interactive/)How Bad Is Your Colormap? (https://jakevdp.github.io/blog/2014/10/16/how­bad­is­your­colormap/)On Frequentism and Fried Chicken (https://jakevdp.github.io/blog/2014/09/02/on­frequentism­and­fried­chicken/)Hacking Academia: Data Science and the University (https://jakevdp.github.io/blog/2014/08/22/hacking­academia/)Frequentism and Bayesianism IV: How to be a Bayesian in Python(https://jakevdp.github.io/blog/2014/06/14/frequentism­and­bayesianism­4­bayesian­in­python/)

Follow @jakevdp 4,012 followers

Copyright © 2012­2014 ­ Jake Vanderplas ­ Powered by Pelican (http://getpelican.com)