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

基于Streamlit实现带可拖拽点的折线图需求及优化问询

实现Streamlit可拖拽点的折线图方案

你想要的是直接在折线图上拖拽点调整数值、同时将数据存入DataFrame的功能,用Altair的交互式拖拽可以完美替代当前的垂直滑块方案,操作更直观,用户体验更好。

改进后的完整代码

import streamlit as st
import pandas as pd
import altair as alt

# 初始化数据
hours = list(range(4, 22))
values_original = [0,3,9,25,62,25,30,30,45,45,28,21,40,55,55,30,10,5,0]

# 用session state保存修改后的数据,避免刷新丢失
if 'edited_values' not in st.session_state:
    st.session_state.edited_values = values_original.copy()

# 创建DataFrame
df_original = pd.DataFrame({'hours': hours, 'Values': values_original, 'Type': 'reference'})
df_edited = pd.DataFrame({'hours': hours, 'Values': st.session_state.edited_values, 'Type': 'project'})

# 创建可拖拽的Altair图表
# 定义点选择器:鼠标悬停时选中最近的点
point_selection = alt.selection_single(
    nearest=True,
    on='mouseover',
    fields=['hours'],
    empty='none'
)

# 可编辑的折线+面积图
edited_chart = alt.Chart(df_edited).mark_area(
    opacity=0.7,
    interpolate='cardinal'
).encode(
    x=alt.X('hours', title='小时', scale=alt.Scale(domain=[4, 22])),
    y=alt.Y('Values:Q', title='数值'),
    fill=alt.Fill(field='Type', title='曲线'),
    tooltip=['hours', alt.Tooltip('Values', title='当前数值')]
).add_selection(
    point_selection
)

# 拖拽点的交互:允许修改选中点的Y值
drag_handler = alt.Chart(df_edited).mark_point(
    size=80,
    fill='white',
    stroke='black'
).encode(
    x='hours:Q',
    y=alt.Y('Values:Q', title='数值'),
).transform_filter(
    point_selection
).add_selection(
    alt.selection_single(
        encodings=['y'],
        on='mousedown',
        translate=['x', 'y'],
        zoom=False,
        name='drag'
    )
).transform_calculate(
    new_values="drag.y !== null ? drag.y : datum.Values"
)

# 原始参考线
original_line = alt.Chart(df_original).mark_line(
    color='red',
    interpolate='cardinal',
    opacity=0.7
).encode(
    x='hours:Q',
    y='Values:Q',
    tooltip=['hours', alt.Tooltip('Values', title='参考数值')]
)

# 组合图表
combined_chart = (edited_chart + drag_handler + original_line).interactive()

# 渲染图表
st.altair_chart(combined_chart, use_container_width=True)

# 同步拖拽后的数据到session state
if 'drag' in st.session_state:
    drag_data = st.session_state.drag
    if drag_data:
        selected_hour = drag_data['hours'][0]
        new_value = drag_data['new_values'][0]
        idx = hours.index(selected_hour)
        st.session_state.edited_values[idx] = round(float(new_value), 1)

# 展示当前编辑后的DataFrame,供模型使用
st.subheader('当前编辑后的数据')
st.dataframe(df_edited)

关键功能说明

  • 拖拽交互:通过Altair的selection_single实现点的选中和拖拽修改Y值,用户可以直接在图上拖动白色带黑边的控制点调整数值
  • 数据持久化:用st.session_state保存修改后的数值,避免Streamlit刷新后数据丢失
  • 数据同步:拖拽后自动更新DataFrame,你可以直接用df_edited或st.session_state.edited_values传入模型
  • 保留参考线:红色参考线始终显示,方便对比原始数据

使用方法

  1. 鼠标悬停在折线的控制点上,按住鼠标拖动即可调整该点的数值
  2. 页面下方会实时展示编辑后的DataFrame,直接取用即可

内容的提问来源于stack exchange,提问作者Mathieu P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:30:54