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

如何用tikzplotlib将Matplotlib FuncAnimation动画转为含完整模拟的TeX文件?

用tikzplotlib结合LaTeX animate包实现动态模拟导出

tikzplotlib本身不直接支持导出动画,但可以通过生成时间序列的TikZ代码片段,再结合LaTeX的animate包实现动态效果。下面提供两种可行方案:


方案一:生成单文件TikZ动画(推荐)

直接生成包含所有时间步数据的LaTeX文件,利用animate包控制帧切换,无需导出多份独立文件。

步骤1:修改Python代码生成动画TeX文件

import numpy as np
from scipy.integrate import solve_ivp
from matplotlib import pyplot as plt
import tikzplotlib

# 原模拟逻辑保持不变
M = 10
sites = np.array(range(M))
N = 3

def lotka(t,x):
    u = x[0:M]
    v = x[M:]
    dudt = u-u*u-u*v
    dvdt = v-u*v-v*v
    dxdt = np.concatenate((dudt,dvdt))
    return dxdt

u0 = np.zeros(M)
v0 = np.zeros(M)
u0[0] = N
v0[-1] = N
if M%2 == 0:
    for i in range(int(M/2)):
        u0[i] = N
        v0[M-1-i] = N
else:
    for i in range(int(np.floor(M/2))-1):
        u0[i] = N
        v0[M-1-i] = N

x0 = np.concatenate((u0,v0))
nt = 500
t = np.linspace(0,0.2,nt)
x = solve_ivp(lotka,[0,4],x0,t_eval=t)

u = np.zeros((nt,M))
v = np.zeros((nt,M))
for i in range(nt):
    u[i] = x.y.T[i][0:M]
    v[i] = x.y.T[i][M:]

# 生成基础静态图模板
fig = plt.figure()
ax = plt.axes()
ax.grid()
ax.plot(sites, u[0], label='u')
ax.plot(sites, v[0], label='v')
ax.text(0.05, 0.9, f'time = {t[0]:.4f}', transform=ax.transAxes)
ax.legend()

base_tikz = tikzplotlib.get_tikz_code(fig)
plt.close()

# 定义所有时间步的数据宏
u_data = '\n'.join([f"    \\def\\u{i}{{{','.join(map(str, u[i]))}}}" for i in range(nt)])
v_data = '\n'.join([f"    \\def\\v{i}{{{','.join(map(str, v[i]))}}}" for i in range(nt)])
time_data = '\n'.join([f"    \\def\\time{i}{{{t[i]:.4f}}}" for i in range(nt)])

# 构建动画TeX文件
animated_tex = f"""
\\documentclass{{standalone}}
\\usepackage{{tikz}}
\\usepackage{{animate}}
\\usepackage{{pgfplots}}
\\pgfplotsset{{compat=1.17}}

\\begin{{document}}
{u_data}
{v_data}
{time_data}

\\begin{{animateinline}}[loop, autoplay, interval=1]
"""

# 为每个时间步生成绘图帧
for i in range(nt):
    # 替换基础模板中的数据为当前帧内容
    frame_content = base_tikz.replace(
        f"table {{{','.join(map(str, u[0]))}}}",
        f"table {{{'\\u'+str(i)}}}"
    ).replace(
        f"table {{{','.join(map(str, v[0]))}}}",
        f"table {{{'\\v'+str(i)}}}"
    ).replace(
        f"time = {t[0]:.4f}",
        f"time = \\time{i}"
    )
    # 提取tikzpicture内部代码
    start_idx = frame_content.find('\\begin{tikzpicture}') + len('\\begin{tikzpicture}')
    end_idx = frame_content.find('\\end{tikzpicture}')
    frame_tikz = frame_content[start_idx:end_idx].strip()
    
    animated_tex += f"\\begin{{tikzpicture}}\n{frame_tikz}\n\\end{{tikzpicture}}\n"
    if i < nt-1:
        animated_tex += "\\newframe\n"

animated_tex += """
\\end{animateinline}
\\end{document}
"""

# 保存文件
with open('simulation_animation.tex', 'w') as f:
    f.write(animated_tex)

print("动画TeX文件已生成:simulation_animation.tex")

步骤2:编译LaTeX文件

使用支持animate包的编译器,需启用shell escape:

pdflatex -shell-escape simulation_animation.tex

编译后的PDF需在支持动画的阅读器(如Adobe Acrobat、Foxit Reader)中打开才能播放。


方案二:导出多帧静态TikZ文件再整合

如果偏好先导出每个帧的独立TikZ文件,再在LaTeX中组合,可按以下步骤操作:

步骤1:修改Python代码导出单帧TikZ文件

# (原模拟逻辑部分保持不变,直到生成u和v数据)

# 逐个导出每一帧的TikZ文件
for i in range(nt):
    fig = plt.figure()
    ax = plt.axes()
    ax.grid()
    ax.plot(sites, u[i], label='u')
    ax.plot(sites, v[i], label='v')
    ax.text(0.05, 0.9, f'time = {t[i]:.4f}', transform=ax.transAxes)
    ax.legend()
    tikzplotlib.save(f'frame_{i:03d}.tex')
    plt.close()

print(f"已导出{nt}个帧文件:frame_000.tex 到 frame_{nt-1:03d}.tex")

步骤2:编写LaTeX主文件

创建animation_main.tex:

\\documentclass{standalone}
\\usepackage{tikz}
\\usepackage{animate}

\\begin{document}
\\begin{animateinline}[loop, autoplay, interval=1]
    \\multiframe{500}{i=0+1}{
        \\input{frame_\\i.tex}
    }
\\end{animateinline}
\\end{document}

注意:\\multiframe{500}{i=0+1}中的500需与你的nt值一致。

步骤3:编译LaTeX文件

同样使用带shell escape的pdflatex编译:

pdflatex -shell-escape animation_main.tex

注意事项

  • 确保LaTeX环境已安装animate、pgfplots、tikz包。
  • 调整interval参数(单位毫秒)可控制动画播放速度。
  • 部分轻量PDF阅读器不支持动画效果,需使用专业阅读器查看。

内容的提问来源于stack exchange,提问作者xounamoun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:35:15