我有一个与下面类似的数据集。请注意,单个ID有多个值。
import pandas as pd
import numpy as np
import random
df = pd.DataFrame({'DATE_TIME':pd.date_range('2022-11-01', '2022-11-05 23:00:00',freq='20min'),
'SBP':[random.uniform(110, 160) for n in range(358)],
'DBP':[random.uniform(60, 100) for n in range(358)],
'ID':[random.randrange(1, 3) for n in range(358)],
'TIMEINTERVAL':[random.randrange(1, 200) for n in range(358)]})
df['VISIT'] = df['DATE_TIME'].dt.day
df['MODE'] = np.select([df['VISIT']==1, df['VISIT'].isin([2,3])], ['CKD', 'Dialysis'], 'Late TPL')
df['TIME'] = df['DATE_TIME'].dt.time
df['TIME'] = df['TIME'].astype('str')
def to_day_period(s):
bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
labels = ['Night', 'Morning', 'Afternoon', 'Evening', 'Night']
return pd.cut(
pd.to_timedelta(s),
bins=list(map(pd.Timedelta, bins)),
labels=labels, right=False, ordered=False
)
df['TIME_OF_DAY'] = to_day_period(df['TIME'])我想使用Dash,这样我就可以先选择ID,然后绘制出所选ID的图,此外,我还做了一个滑块,以分钟来选择测量之间的时间间隔。此滑块应分别适用于晨光值和夜间值。所以,我已经实现了一个滑块,它可以在白天和夜间工作。我想要两个滑块,一个用于早晨值从06:00到17:59,另一个称为夜从18 :59到05:59。
from dash import Dash, html, dcc, Input, Output
import pandas as pd
import os
import plotly.express as px
# FUNCTION TO CHOOSE A SINGLE PATIENT
def choose_patient(dataframe_name, id_number):
return dataframe_name[dataframe_name['ID']==id_number]
# FUNCTION TO CHOOSE A SINGLE PATIENT WITH A SINGLE VISIT
def choose_patient_visit(dataframe_name, id_number,visit_number):
return dataframe_name[(dataframe_name['ID']==id_number) & (dataframe_name['VISIT']==visit_number)]
# READING THE DATA
df = pd.read_csv(df,sep=',',parse_dates=['DATE_TIME','DATE'], infer_datetime_format=True)
# ---------------------------------------------------- dash example ----------------------------------------------------
app = Dash(__name__)
app.layout = html.Div([
html.H4('Interactive Scatter Plot'),
dcc.Graph(id="scatter-plot",style={'width': '130vh', 'height': '80vh'}),
html.P("Filter by time interval:"),
dcc.Dropdown(df.ID.unique(), id='pandas-dropdown-1'), # for choosing ID,
dcc.RangeSlider(
id='range-slider',
min=0, max=600, step=10,
marks={0: '0', 50: '50', 100: '100', 150: '150', 200: '200', 250: '250', 300: '300', 350: '350', 400: '400',
450: '450', 500: '500', 550: '550', 600: '600'},
value=[0, 600]
),
html.Div(id='dd-output-container')
])
@app.callback(
Output("scatter-plot", "figure"),
Input("pandas-dropdown-1", "value"),
Input("range-slider", "value"),
prevent_initial_call=True)
def update_lineplot(value, slider_range):
low, high = slider_range
df1 = df.query("ID == @value & TIMEINTERVAL >= @low & TIMEINTERVAL < @high").copy()
if df1.shape[0] != 0:
fig = px.line(df1, x="DATE_TIME", y=["SBP", "DBP"],
hover_data=['TIMEINTERVAL'], facet_col='VISIT',
facet_col_wrap=2,
symbol='MODE',
facet_row_spacing=0.1,
facet_col_spacing=0.09)
fig.update_xaxes(matches=None, showticklabels=True)
return fig
else:
return dash.no_update
app.run_server(debug=True, use_reloader=False)如何实现这两个滑块?一个滑块应用于TIME_OF_DAY列的夜间值,另一个用于TIME_OF_DAY列的晨值。我看Dash网站,但没有这样的工具可用。
发布于 2022-11-27 17:13:41
下面的解决方案只需要对示例代码进行小范围的修改。它实际上过滤了原始数据两次(一次用于时间_OF_DAY=‘Night’,一次用于时间_OF_DAY=‘Morning’),并在绘制之前将它们连接起来。
我还修改了to_day_period函数中的回收箱,使其只生成两个与文本中的请求相匹配的标签(“早晨值从06:00到17:59,.夜从18 :59到05:59”),但是破折号代码可以类似地用于更多的类别。
bins = ['0', '06:00:00', '18:00:00', '24:00:00']
labels = ['Night', 'Morning', 'Night']破折号码
app = Dash(__name__)
app.layout = html.Div([
html.H4('Interactive Scatter Plot with ABPM dataset'),
html.P("Select ID:"),
dcc.Dropdown(df.ID.unique(), id='pandas-dropdown-1'), # for choosing ID,
html.P("Filter by time interval during nighttime (18:00-6:00):"),
dcc.RangeSlider(
id='range-slider-night',
min=0, max=600, step=10,
marks={0: '0', 50: '50', 100: '100', 150: '150', 200: '200', 250: '250', 300: '300', 350: '350', 400: '400',
450: '450', 500: '500', 550: '550', 600: '600'},
value=[0, 600]
),
html.P("Filter by time interval during daytime (6:00-18:00):"),
dcc.RangeSlider(
id='range-slider-morning',
min=0, max=600, step=10,
marks={0: '0', 50: '50', 100: '100', 150: '150', 200: '200', 250: '250', 300: '300', 350: '350', 400: '400',
450: '450', 500: '500', 550: '550', 600: '600'},
value=[0, 600]
),
dcc.Graph(id="scatter-plot", style={'width': '130vh', 'height': '80vh'}),
html.Div(id='dd-output-container')
])
@app.callback(
Output("scatter-plot", "figure"),
Input("pandas-dropdown-1", "value"),
Input("range-slider-night", "value"),
Input("range-slider-morning", "value"),
prevent_initial_call=True)
def update_lineplot(value, slider_range_night, slider_range_morning):
low_night, high_night = slider_range_night
low_morning, high_morning = slider_range_morning
df_night = df.query("ID == @value & TIME_OF_DAY == 'Night' & TIMEINTERVAL >= @low_night & TIMEINTERVAL < @high_night").copy()
df_morning = df.query("ID == @value & TIME_OF_DAY == 'Morning' & TIMEINTERVAL >= @low_morning & TIMEINTERVAL < @high_morning").copy()
df1 = pd.concat([df_night, df_morning], axis=0).sort_values(['TIME'])
if df1.shape[0] != 0:
fig = px.line(df1, x="DATE_TIME", y=["SBP", "DBP"],
hover_data=['TIMEINTERVAL'], facet_col='VISIT',
facet_col_wrap=2,
symbol='MODE',
facet_row_spacing=0.1,
facet_col_spacing=0.09)
fig.update_xaxes(matches=None, showticklabels=True)
return fig
else:
return no_update
app.run_server(debug=True, use_reloader=False)应用程序
在下面的截图中,对TIMEINTERVAL的所有“早晨”/“白天”观测进行了过滤,而“夜间”观测没有受到影响:

https://stackoverflow.com/questions/74448717
复制相似问题