具有datetime和散点图交互的plotly dash range滑块

2024-05-29 05:38:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在我的下拉列表中添加一个范围滑块,并使范围滑块成为“Wallclock”日期时间,以及一个允许范围滑块根据下拉值为该胶囊选择日期时间的交互。我设法找到了其他人做这件事的几种方法,但似乎没有一种适合我的情况,特别是回调和更新图表。谢谢大家!

数据如下所示

enter image description here

Dash看起来像这样

enter image description here

代码看起来像这样

import pandas as pd
import plotly.express as px  # (version 4.7.0)
import plotly.graph_objects as go
import numpy as np

import openpyxl
import dash  # (version 1.12.0) pip install dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__)
server = app.server

df = pd.read_excel("tcd vs rh 2.xlsx")
print(df)

capsuleID = df['Capsule_ID'].unique()
print(capsuleID)

capsuleID_names = sorted(list(capsuleID))
print(capsuleID_names)

capsuleID_names_1 = [{'label': k, 'value': k} for k in sorted(capsuleID)]
capsuleID_names_2 = [{'label': '(Select All)', 'value': 'All'}]
capsuleID_names_all = capsuleID_names_1 + capsuleID_names_2

app.layout = html.Div([

    html.H1("Relative Humidity vs TCD", style={'text-align': 'center'}),

    dcc.Dropdown(id="capsule_select",
                 options=capsuleID_names_all,
                 optionHeight=25,
                 multi=True,
                 searchable=True,
                 placeholder='Please select...',
                 clearable=True,
                 value=['All'],
                 style={'width': "100%"}
                 ),

    dcc.RangeSlider(id='slider',
                    min=df['Wallclock'].min(),
                    max=df['Wallclock'].max(),
                    value=[df.iloc[-101]['Wallclock'].timestamp(), df.iloc[-1]['Wallclock'].timestamp()]
                    ),

    html.Div([
        dcc.Graph(id="the_graph"),
    ]),

])

# -----------------------------------------------------------
@app.callback(
    Output('the_graph', 'figure'),
    Output('capsule_select', 'value'),
    Input('capsule_select', 'value'),
    Input('slider', 'value'),
)
def update_graph(capsule_chosen):
    lBound = pd.to_datetime(value[0], unit='s')
    uBound = pd.to_datetime(value[1], unit='s')
    filteredData = df.loc[(df['date'] >= lBound) & (df['date'] <= uBound)]

    dropdown_values = capsule_chosen

    if "All" in capsule_chosen:
        dropdown_values = capsuleID_names
        dff = df
    else:
        dff = df[df['Capsule_ID'].isin(capsule_chosen)]  # filter all rows where capsule ID is the capsule ID selected

    scatterplot = px.scatter(
        data_frame=dff,
        x="tcd",
        y="humidity",
        hover_name="Wallclock",
    )

    scatterplot.update_traces(textposition='top center')

    return scatterplot, dropdown_values


# ------------------------------------------------------------------------------

if __name__ == '__main__':
    app.run_server(debug=True)


Tags: importidappdfnamesvaluehtmlas
1条回答
网友
1楼 · 发布于 2024-05-29 05:38:09
  • 显然,我无法访问您的Excel电子表格,因此生成了一个形状相同的数据框
  • 使用第二个图形的范围滑块来实现滑块功能
  • 更新了回调,以使用此数字作为日期范围的输入
  • 使用jupyter dash inline,可以将其更改回您的设置(注释行)

生成一些样本数据

import pandas as pd
import numpy as np
df = pd.DataFrame(
    {
        "Wallclock": pd.date_range(
            "22-dec-2020 00:01:36", freq="5min", periods=2000
        ),
        "tcd": np.linspace(3434, 3505, 2000) *np.random.uniform(.9,1.1, 2000),
        "humidity": np.linspace(63, 96, 2000),
    }
).pipe(lambda d: d.assign(Capsule_ID=(d.index // (len(d)//16))+2100015))

滑块是一个带有rangeslider

import pandas as pd
import plotly.express as px  # (version 4.7.0)
import plotly.graph_objects as go
import numpy as np

import openpyxl
import dash  # (version 1.12.0) pip install dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
from jupyter_dash import JupyterDash

# app = dash.Dash(__name__)
# server = app.server
app = JupyterDash(__name__)


# df = pd.read_excel("tcd vs rh 2.xlsx")
# print(df)

capsuleID = df["Capsule_ID"].unique()
# print(capsuleID)

capsuleID_names = sorted(list(capsuleID))
# print(capsuleID_names)

capsuleID_names_1 = [{"label": k, "value": k} for k in sorted(capsuleID)]
capsuleID_names_2 = [{"label": "(Select All)", "value": "All"}]
capsuleID_names_all = capsuleID_names_1 + capsuleID_names_2

def slider_fig(df):
    return px.scatter(
                df.groupby("Wallclock", as_index=False).size(), x="Wallclock", y="size"
            ).update_layout(
                xaxis={"rangeslider": {"visible": True}, "title":None},
                height=125,
                yaxis={"tickmode": "array", "tickvals": [], "title": None},
                margin={"l": 0, "r": 0, "t": 0, "b": 0},
            )

app.layout = html.Div(
    [
        html.H1("Relative Humidity vs TCD", style={"text-align": "center"}),
        dcc.Dropdown(
            id="capsule_select",
            options=capsuleID_names_all,
            optionHeight=25,
            multi=True,
            searchable=True,
            placeholder="Please select...",
            clearable=True,
            value=["All"],
            style={"width": "100%"},
        ),
        dcc.Graph(
            id="slider",
            figure=slider_fig(df),
        ),
        html.Div(
            [
                dcc.Graph(id="the_graph"),
            ]
        ),
    ]
)

#                              -
@app.callback(
    Output("the_graph", "figure"),
    Output("capsule_select", "value"),
    Output("slider", "figure"),
    Input("capsule_select", "value"),
    Input('slider', 'relayoutData'),
    State("slider", "figure")
)
def update_graph(capsule_chosen, slider, sfig):
    dropdown_values = capsule_chosen

    if "All" in capsule_chosen:
        dropdown_values = capsuleID_names
        dff = df
    else:
        dff = df[
            df["Capsule_ID"].isin(capsule_chosen)
        ]  # filter all rows where capsule ID is the capsule ID selected

    
    if slider and "xaxis.range" in slider.keys():
        dff = dff.loc[dff["Wallclock"].between(*slider["xaxis.range"])]
    else:
        # update slider based on selected capsules
        sfig = slider_fig(dff)
        
    scatterplot = px.scatter(
        data_frame=dff,
        x="tcd",
        y="humidity",
        hover_name="Wallclock",
    )

    scatterplot.update_traces(textposition="top center")

    return scatterplot, dropdown_values, sfig


#                                        

if __name__ == "__main__":
    #     app.run_server(debug=True)
    app.run_server(mode="inline")

相关问题 更多 >

    热门问题