3分钟跑通洛伦兹吸引子:Python + Manim 混沌系统可视化指南
【免费下载链接】videosCode for the manim-generated scenes used in 3blue1brown videos项目地址: https://gitcode.com/GitHub_Trending/vi/videos
两个从仅相差 0.00001 的起点出发的点,30 秒后落在完全不相干的位置,但每一步都由固定方程决定。在 3Blue1Brown 动画源码库(GitHub 推荐项目 vi/videos)里跑一条命令,洛伦兹吸引子(一组方程把轨迹卷成的形状)就转起来:这是混沌系统可视化最直接的形态,核心代码只有几十行。
三步跑通:装依赖、拉仓库、一条命令出画面
场景代码在 _2024/manim_demo/lorenz.py,需要三样东西:3b1b 版 Manim(命令行工具叫manimgl,社区版装出来跑不了这个场景)、SciPy、以及渲染 LaTeX 公式的 texlive。
pip install numpy scipy # manimgl 按 3b1b 官方说明从源码安装,Ubuntu 再装: # sudo apt install texlive texlive-latex-extra git clone https://gitcode.com/GitHub_Trending/vi/videos cd videos manimgl _2024/manim_demo/lorenz.py LorenzAttractor -p这段先装依赖、拉仓库,最后一条命令直接渲染并预览场景;嫌慢就先加-ql用低分辨率试跑。
看图说话:洛伦兹吸引子为什么是两片"翅膀"
动画里,黑色背景上立着 3D 坐标轴,左上角写着三个微分方程,x、y、z 分别染成红、绿、蓝。十条深浅不同的蓝色曲线从同一位置出发,每条后面跟一个发光小点,摄像机绕着缓缓转圈。曲线整体卷成两片镜像对称的"翅膀",轨迹在左右两翼之间不断切换,30 秒内不重复经过同一个位置。
这个形状不是画出来的,是方程自己卷出来的。模型描述热空气对流:z 表示上下温差(高度),x、y 是水平流速。轨迹停在某一翼时,"热气流"会把它推向另一侧,而何时推、推多重,取决于状态里极细微的差别。吸引子(轨迹最终被卷入、反复绕行的那片区域)恰好是两翼并排的结构,所以只能左右横跳。十条线一开始重叠、随后逐条分开,是因为起点在 z 方向只差了 1e-5——系统把这个差别指数级放大,最后各落在不同翅膀上。这就是"蝴蝶效应"的完整机制。
原理拆解:洛伦兹方程 + 一次数值积分
整个文件的核心只有两个函数。第一个定义洛伦兹方程组——一组非线性微分方程(变化率由当前位置算出,解不出封闭公式,只能逐步推进):
def lorenz_system(t, state, sigma=10, rho=28, beta=8/3): x, y, z = state return [sigma*(y-x), x*(rho-z)-y, x*y-beta*z] def ode_solution_points(function, state0, time, dt=0.01): sol = solve_ivp(function, (0, time), y0=state0, t_eval=np.arange(0, time, dt)) return sol.y.T # (n_points, 3) 轨迹点第一个函数给出任意状态点的三个变化率:σ(y−x) 让 x、y 速度差互相混匀,x(ρ−z)−y 让高度 z 调制放大强度,xy−βz 是耗散。第二个函数把方程交给solve_ivp做数值积分(反复计算"下一时刻在哪",每 0.01 秒记一个点拼成轨迹),返回的数组直接就是可绘制的点云。
三个参数各管一摊:σ=10 是混合比例,β=8/3 是耗散强度,ρ=28 是对流强度——低于约 24.7 时系统收敛到静止点,升到 28 进入经典混沌区。场景真正的主角在初始条件这一行:
epsilon = 1e-5 states = [[10, 10, 10 + n*epsilon] for n in range(10)]沿 z 方向以 0.00001 的间隔取 10 个起点,后面的动画就是求解这 10 条轨迹,再用ThreeDAxes.c2p把数据坐标映射到屏幕、set_points_smoothly连成光滑曲线。
动手实验:改三个地方看混沌轨迹分岔
- 把 epsilon 改成 0:十条轨迹完全重合为一条,证明分岔确实来自初始条件,而不是求解器引入的随机性。
- 把 rho 从 28 改成 16.8:翅膀消失,轨迹螺旋收敛到一个固定点;再调大到 99,还是那个吸引子,但换翼明显更剧烈。同一个方程组,改一个数就换了一种状态。
- 换另一个混沌系统:用 Rössler 方程替换
lorenz_system:dx/dt=−y−z,dy/dt=x+a·y,dz/dt=b+z·(x−c),取 a=0.2、b=0.2、c=5.7。你会看到一条平面盘旋很久、再猛地一翻的"过山车"轨道——形状变了,对初值敏感的脾气没变。
延伸方向:把同一套绘制管线用到别的系统
- 算出差别的放大速度:每帧记录相邻两点的距离,画 ln(距离) 对时间的折线,斜率就是李雅普诺夫指数的近似,这是衡量混沌强度的标准量。
- 复用
solve_ivp+c2p+set_points_smoothly这条 3D 轨迹管线:换掉方程函数,就能画天体轨道、捕食者-猎物模型等任何 ODE 系统的相图。 - 仓库里同门的例子:_2018/turbulence.py 做流场与湍流的可视化,_2015/ka_playgrounds/fluid_flow.py 演示对流类流场的演化,都和本文的例子同源。
【免费下载链接】videosCode for the manim-generated scenes used in 3blue1brown videos项目地址: https://gitcode.com/GitHub_Trending/vi/videos
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考