Animating the Lorenz System in 3D
-
Upload
dhruv-singh -
Category
Documents
-
view
14 -
download
4
description
Transcript of 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/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 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, firstorder,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 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 looksstraightforward, for certain choices of the parameters , the trajectories become chaotic, and the resulting trajectoriesdisplay some surprising properties.
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 indepth in a previous post(/blog/2012/08/18/matplotlibanimationtutorial/), 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)
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:])
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 drawin all paths: these are the socalled "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
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" ???
eldada • 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 ›
• 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 > eldada
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 ofbuiltin 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 circlelike 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 socalled "saddlefocus"."Focus" means that there is a twodimensional object like a plane (the socalled "stablemanifold") where the trajectory approaches the fixed point asymptotically in a spiral; this iswhat you are seeing in the simulation. However, perpendicular to this planarlike object is aonedimensional 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* onedimensional stable direction, and an *unstable* twodimensionalsubspace (for the linearised system) and hence a twodimensional 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 ›
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 doublechecked :)
• 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 buitin 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 ›
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 aFortranordered 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/thehipstereffectinteractive/)How Bad Is Your Colormap? (https://jakevdp.github.io/blog/2014/10/16/howbadisyourcolormap/)On Frequentism and Fried Chicken (https://jakevdp.github.io/blog/2014/09/02/onfrequentismandfriedchicken/)Hacking Academia: Data Science and the University (https://jakevdp.github.io/blog/2014/08/22/hackingacademia/)Frequentism and Bayesianism IV: How to be a Bayesian in Python(https://jakevdp.github.io/blog/2014/06/14/frequentismandbayesianism4bayesianinpython/)
Follow @jakevdp 4,012 followers
Copyright © 20122014 Jake Vanderplas Powered by Pelican (http://getpelican.com)