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

在Streamlit中制作多线动态折线图的最优方案探讨

Streamlit大数量动态折线图优化方案

当前Matplotlib GIF方案的局限性

  • 生成GIF需要预渲染所有帧,参数变更后重新生成耗时,数据量越大(50条线+多帧),等待时间越长
  • GIF格式无交互性,无法查看具体数据点、缩放图表
  • 临时文件管理增加额外复杂度

推荐方案

方案1:Streamlit原生组件+动态更新(轻量高效)

利用st.empty()占位,配合循环实时更新折线图,无需预生成所有帧,参数变更后直接重新计算并启动新动画循环,适合轻量快速迭代场景。

import streamlit as st
import numpy as np
import pandas as pd
import time

# 侧边栏参数
Z = st.sidebar.slider("Number of Ensembles", min_value=10, max_value=50, value=20, step=10)
frame_count = st.sidebar.slider("动画帧数", min_value=20, max_value=100, value=50)

# 初始化X轴数据(40个点)
x = np.linspace(0, 2 * np.pi, 40)
line_num = 50  # 50条折线

# 准备图表容器
chart_placeholder = st.empty()
st.title("实时更新动态折线图")

# 动画循环
for frame in range(frame_count):
    # 参数变更后重新计算当前帧所有折线数据
    y_data = np.array([np.sin(x + frame/10 + phase*Z) for phase in np.linspace(0, 2 * np.pi, line_num)])
    df = pd.DataFrame(y_data.T, index=x)
    # 更新图表
    chart_placeholder.line_chart(df)
    # 控制帧率
    time.sleep(0.1)

方案2:Plotly动画(支持交互,性能优异)

Plotly原生支持动画功能,Streamlit可直接渲染Plotly图表,自带缩放、hover查看数据点等交互,处理多折线效率高于Matplotlib,参数变更后重生成速度更快。

import streamlit as st
import numpy as np
import pandas as pd
import plotly.express as px

# 侧边栏参数
Z = st.sidebar.slider("Number of Ensembles", min_value=10, max_value=50, value=20, step=10)
frame_count = st.sidebar.slider("动画帧数", min_value=20, max_value=100, value=50)

# 基础数据定义
x = np.linspace(0, 2 * np.pi, 40)
line_num = 50
phases = np.linspace(0, 2 * np.pi, line_num)

# 构造包含所有帧的DataFrame
data = []
for frame in range(frame_count):
    for line_idx, phase in enumerate(phases):
        y = np.sin(x + frame/10 + phase*Z)
        for xi, yi in zip(x, y):
            data.append({
                "X": xi,
                "Y": yi,
                "折线ID": f"Line {line_idx+1}",
                "帧": frame
            })
df = pd.DataFrame(data)

# 创建Plotly动画图
fig = px.line(df, x="X", y="Y", color="折线ID", animation_frame="帧",
              range_y=[-1.2, 1.2])  # 固定Y轴范围避免动画跳动

# 在Streamlit中展示
st.title("Plotly交互式动态折线图")
st.plotly_chart(fig, use_container_width=True)

方案3:缓存优化+原生更新(减少重复计算)

用st.cache_data缓存计算结果,避免参数变更时重复执行耗时的计算逻辑,结合动态更新进一步提升性能,适合计算密集型场景。

import streamlit as st
import numpy as np
import pandas as pd
import time

# 缓存数据计算函数,参数变更时自动重新计算
@st.cache_data
def calculate_all_frames(Z, frame_count, line_num=50, x_len=40):
    x = np.linspace(0, 2 * np.pi, x_len)
    phases = np.linspace(0, 2 * np.pi, line_num)
    all_frames = []
    for frame in range(frame_count):
        y_data = np.array([np.sin(x + frame/10 + phase*Z) for phase in phases])
        df = pd.DataFrame(y_data.T, index=x)
        all_frames.append(df)
    return all_frames

# 侧边栏参数
Z = st.sidebar.slider("Number of Ensembles", min_value=10, max_value=50, value=20, step=10)
frame_count = st.sidebar.slider("动画帧数", min_value=20, max_value=100, value=50)

# 获取缓存的所有帧数据
all_frames = calculate_all_frames(Z, frame_count)

# 动画展示
chart_placeholder = st.empty()
st.title("缓存优化的动态折线图")

for df in all_frames:
    chart_placeholder.line_chart(df)
    time.sleep(0.1)

方案对比

方案优点缺点适用场景
Matplotlib生成GIF兼容旧环境,无额外依赖无交互,预渲染耗时,临时文件复杂仅需静态动画展示的场景
Streamlit原生动态更新轻量、代码简单,实时渲染交互性弱(仅基础缩放)快速原型、轻量动画场景
Plotly动画强交互,性能优异,支持复杂配置数据构造稍复杂需要交互功能的正式场景
缓存+原生更新减少重复计算,性能最优预缓存占用少量内存计算密集型参数变更场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:43:09