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

如何在Plotly Dash中基于用户选择的时间戳范围更新图表?

问题:在Dash中实现精确到时分秒的时间戳范围选择

我正在用Python的Plotly Dash开发交互式仪表盘,其中有个折线图需要根据用户选择的时间范围更新。目前已经实现了dcc.DatePickerRange组件来按日期范围更新图表,但找不到支持精确到时分秒的时间戳范围选择的选项,查文档和社区也没结果,想知道能不能在Dash里实现“从[时间戳]到[时间戳]”的范围选择来替代日期选择器。

数据集片段:

timestamp            date        id  lat         lon         mode   temperature
0   2022-04-01 13:48:38  2022-04-01  15  52.5170365  13.3888599  AUTO   33
1   2022-04-01 13:48:40  2022-04-01  15  52.5170365  13.3888599  AUTO   33
2   2022-04-01 13:48:42  2022-04-01  15  52.5170365  13.3888599  AUTO   33
3   2022-04-02 13:49:18  2022-04-02  15  52.5170375  13.3888605  AUTO   30
4   2022-04-02 13:49:34  2022-04-02  15  52.5170375  13.3888605  AUTO   30
5   2022-04-02 13:49:52  2022-04-02  15  52.5170375  13.3888605  AUTO   30
6   2022-04-03 13:50:10  2022-04-03  15  52.5170385  13.3888609  AUTO   31
7   2022-04-03 13:50:46  2022-04-03  15  52.5170385  13.3888609  AUTO   31
8   2022-04-04 13:51:24  2022-04-04  15  52.5170395  13.3888614  AUTO   34
9   2022-04-04 13:51:46  2022-04-04  15  52.5170395  13.3888614  AUTO   34

已实现的日期选择器代码:

import pandas as pd
from datetime import datetime as dt
from datetime import date
import dash
import dash_daq as daq
from dash import dcc, html, Input, Output, State
import dash_bootstrap_components as dbc
from jupyter_dash import JupyterDash
import plotly.express as px
import plotly.graph_objects as go

# df = # 上述数据集

app = JupyterDash(__name__)

app.layout = html.Div(
    [
        dcc.DatePickerRange(
            id="date_filter",
            initial_visible_month=dt(dt.today().year, 8, 1).date(),
            start_date=df['date'].min(),
            end_date=df['date'].max(),
            show_outside_days=True,
            day_size=32,
            display_format='DD/MM/YYYY',
            clearable=True,
            style={'text-align':'left', 'width': '6', 'font-size': '10'}
        ),
        dcc.Graph(id="graph"),
    ]
)


@app.callback(
    Output("graph", "figure"),
    Input("date_filter", "start_date"),
    Input("date_filter", "end_date"),
)
def updateGraph(start_date, end_date):
    if not start_date or not end_date:
        raise dash.exceptions.PreventUpdate
    else:
        return px.line(
            df.loc[
                df["date"].between(
                    pd.to_datetime(start_date), pd.to_datetime(end_date)
                )
            ],
            x="date",
            y="temperature",
        )


# 在笔记本中运行并显示结果
app.run_server(mode="inline")

解决方案

Dash原生组件没有直接的“时间戳范围选择器”,但可以通过以下两种方式实现精确到时分秒的时间范围筛选:

方法1:使用两个dcc.Input组件(类型为datetime-local)

利用HTML5的datetime-local输入类型,让用户可以选择包含时分秒的时间戳,再通过回调实现范围筛选。

修改后的完整代码:

import pandas as pd
from datetime import datetime as dt
import dash
from dash import dcc, html, Input, Output
from jupyter_dash import JupyterDash
import plotly.express as px

# 加载数据集,确保timestamp列转为datetime类型
df = pd.read_csv("your_data.csv")  # 替换为你的数据加载方式
df['timestamp'] = pd.to_datetime(df['timestamp'])

app = JupyterDash(__name__)

app.layout = html.Div(
    [
        html.Div([
            html.Label("开始时间戳:"),
            dcc.Input(
                id="start_timestamp",
                type="datetime-local",
                value=df['timestamp'].min().strftime('%Y-%m-%dT%H:%M:%S'),
                style={"margin-right": "20px"}
            ),
            html.Label("结束时间戳:"),
            dcc.Input(
                id="end_timestamp",
                type="datetime-local",
                value=df['timestamp'].max().strftime('%Y-%m-%dT%H:%M:%S')
            )
        ], style={"margin-bottom": "20px"}),
        dcc.Graph(id="graph"),
    ]
)


@app.callback(
    Output("graph", "figure"),
    Input("start_timestamp", "value"),
    Input("end_timestamp", "value"),
)
def updateGraph(start_timestamp, end_timestamp):
    if not start_timestamp or not end_timestamp:
        raise dash.exceptions.PreventUpdate
    
    # 转换为datetime对象
    start = pd.to_datetime(start_timestamp)
    end = pd.to_datetime(end_timestamp)
    
    # 筛选时间范围内的数据
    filtered_df = df.loc[df["timestamp"].between(start, end)]
    
    return px.line(filtered_df, x="timestamp", y="temperature")


app.run_server(mode="inline")

说明:

  • datetime-local类型的输入框会弹出带时间选择的日历,支持精确到分钟(部分浏览器支持秒级选择)
  • 需要将timestamp列转为datetime类型,确保筛选逻辑正确
  • 初始值通过strftime('%Y-%m-%dT%H:%M:%S')格式化,符合datetime-local的输入格式要求

方法2:使用dash-bootstrap-components的DatePickerRange结合时间输入框

如果希望保留日历选择的交互,同时补充时间输入,可以将日期选择器和时间输入框组合,拼接成完整的时间戳。

示例代码片段:

import dash_bootstrap_components as dbc

app.layout = html.Div(
    [
        dbc.Row([
            dbc.Col(dcc.DatePickerRange(
                id="date_range",
                start_date=df['date'].min(),
                end_date=df['date'].max(),
                display_format='DD/MM/YYYY'
            ), width=6),
            dbc.Col([
                html.Div([
                    html.Label("开始时间:"),
                    dcc.Input(id="start_time", type="time", value="00:00:00")
                ]),
                html.Div([
                    html.Label("结束时间:"),
                    dcc.Input(id="end_time", type="time", value="23:59:59")
                ])
            ], width=6)
        ], style={"margin-bottom": "20px"}),
        dcc.Graph(id="graph"),
    ]
)

@app.callback(
    Output("graph", "figure"),
    Input("date_range", "start_date"),
    Input("date_range", "end_date"),
    Input("start_time", "value"),
    Input("end_time", "value"),
)
def updateGraph(start_date, end_date, start_time, end_time):
    if not start_date or not end_date or not start_time or not end_time:
        raise dash.exceptions.PreventUpdate
    
    # 拼接日期和时间为完整时间戳
    start_timestamp = pd.to_datetime(f"{start_date} {start_time}")
    end_timestamp = pd.to_datetime(f"{end_date} {end_time}")
    
    filtered_df = df.loc[df["timestamp"].between(start_timestamp, end_timestamp)]
    
    return px.line(filtered_df, x="timestamp", y="temperature")

说明:

  • 这种方式兼顾了日期选择的便捷性和时间精度的需求
  • 通过dcc.Input(type="time")组件获取时分秒,和日期选择器的结果拼接成完整时间戳

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:25:26