You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求解析Python中Matplotlib正弦曲线动画脚本的工作原理

正弦曲线联动动画代码详解

这段Python代码用Matplotlib实现了单位圆与正弦曲线联动的动态效果:左侧单位圆上的红点随角度移动,右侧同步绘制对应角度的正弦曲线,二者用虚线实时连接,最终导出为5秒、60fps的MP4动画。下面拆解各部分的作用:

1. 依赖导入与路径配置

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation 
from matplotlib.patches import ConnectionPatch 
import os

desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
  • 导入的库各司其职:plt负责绘图基础操作,numpy处理数学计算,animation实现动画核心逻辑,ConnectionPatch绘制跨子图的虚线,os处理文件路径
  • desktop_path:获取当前用户的桌面路径,后续将生成的动画保存在该位置

2. 绘图布局初始化

fig, (axl, axr) = plt.subplots(
    ncols=2,
    sharey=True,
    figsize=(12, 4),
    gridspec_kw=dict(width_ratios=[1, 3], wspace=0.1),
)
axl.set_aspect(1)
axr.set_box_aspect(1 / 3)
axr.yaxis.set_visible(False)
axr.xaxis.set_ticks([0, np.pi, 2 * np.pi], ["0", r"$\pi$", r"$2\pi$"])
  • 创建左右两个子图:axl对应左侧单位圆画布,axr对应右侧正弦曲线画布
  • sharey=True:让两个子图共享Y轴范围(均为[-1,1]),保证视觉上的坐标对应关系
  • width_ratios=[1,3]:设置左子图宽度为右子图的1/3,wspace=0.1缩小子图间距,让整体布局更紧凑
  • axl.set_aspect(1):强制左子图为正方形,避免单位圆被拉伸变形
  • axr.set_box_aspect(1/3):设置右子图宽高比为3:1,适配正弦曲线X轴0到2π的范围
  • 隐藏右子图Y轴,自定义X轴刻度为数学符号,让画面更简洁专业

3. 静态元素绘制

theta = np.linspace(0, 2 * np.pi, 50)
axl.plot(np.cos(theta), np.sin(theta), "k", lw=1)
point, = axl.plot(0, 0, "o", color='red')

sine, = axr.plot(theta, np.sin(theta), color='blue')

con = ConnectionPatch(
    (1, 0),
    (0, 0),
    "data",
    "data",
    axesA=axl,
    axesB=axr,
    color="C0",
    ls="dotted",
)
fig.add_artist(con)
  • 绘制单位圆:用50个均匀分布的角度点计算单位圆坐标,画出黑色细线的圆作为基础背景
  • 初始化移动红点:point, = ...的逗号用于获取plot返回的单个Line2D对象,后续动画会实时更新这个点的位置
  • 初始化正弦曲线:同样获取Line2D对象,后续动态更新它的绘制范围
  • 创建跨子图虚线:初始连接左子图(1,0)(单位圆右顶点)和右子图(0,0),指定虚线样式后添加到画布,后续会随红点移动更新连接位置

4. 动画核心更新函数

def animate(i):
    x = np.linspace(0, i, int(i * 25 / np.pi))
    sine.set_data(x, np.sin(x))
    x, y = np.cos(i), np.sin(i)
    point.set_data([x], [y])
    con.xy1 = x, y
    con.xy2 = i, y
    return point, sine, con

这是每帧动画的核心逻辑,参数i是当前帧对应的角度值(从0到2π):

  • 更新正弦曲线:生成从0到当前角度i的X轴数据,计算对应的正弦值,用set_data让曲线只绘制到当前角度,实现“逐步画曲线”的效果
  • 更新红点位置:计算当前角度对应的单位圆坐标,更新红点的位置
  • 更新连接虚线:把虚线的两端分别绑定到左侧红点和右侧正弦曲线上的对应点,保证二者始终联动
  • 返回需要重绘的元素:告诉Matplotlib这三个元素在当前帧需要刷新

5. 动画配置与导出

fps = 60
duration = 5  
total_frames = fps * duration

frames = np.linspace(0, 2 * np.pi, total_frames)
ani = animation.FuncAnimation(
    fig,
    animate,
    frames=frames,
    interval=1000/fps,  
    blit=False,
    repeat=True,
)

output_path = os.path.join(desktop_path, "animation_seno-2.mp4")

Writer = animation.writers['ffmpeg']
writer = Writer(fps=fps, metadata=dict(artist='Lenin'), bitrate=1800)
ani.save(output_path, writer=writer)

plt.show()
  • 帧率与总帧数:设置60fps、5秒时长,总共有300帧动画
  • 角度序列:生成300个从0到2π的均匀角度值,每个角度对应一帧
  • 创建动画对象:FuncAnimation循环调用animate函数,每帧传入一个角度值;interval设置每帧间隔(约16.67ms),repeat=True让动画循环播放
  • 导出动画:指定保存路径,用ffmpeg作为编码器,设置帧率、作者元数据和比特率,最后保存为MP4文件
  • plt.show():弹出窗口显示动画

内容的提问来源于stack exchange,提问作者Lenin de Castilhos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:40:57