I have a dataset which is similar to below one. Please note that there are multiple values for a single 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='h'),
'SBP':[random.uniform(110, 160) for n in range(120)],
'DBP':[random.uniform(60, 100) for n in range(120)],
'ID':[random.randrange(1, 100) for n in range(120)],
'TIMEINTERVAL':[random.randrange(1, 200) for n in range(120)]})
df['VISIT'] = df['DATE_TIME'].dt.day
df['MODE'] = np.select([df['VISIT']==1, df['VISIT'].isin([2,3])], ['New', 'InProgress'], 'Done')
I use the following DASH code to make slider:
app = Dash(__name__)
app.layout = html.Div([
html.H4('Interactive Scatter Plot with ABPM dataset'),
dcc.Graph(id="scatter-plot"),
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_bar_chart(value,slider_range):
low, high = slider_range
df1 = df.query("ID == @value & TIMEINTERVAL > @low & TIMEINTERVAL < @high").copy()
if df1.shape[0] != 0:
fig = px.scatter(df1, x="DATE_TIME", y=["SBP","DBP"],
hover_data=['TIMEINTERVAL'],facet_col='VISIT',
facet_col_wrap=2,
symbol='MODE')
fig.update_xaxes(matches= None, showticklabels=True)
return fig
else:
return dash.no_update
app.run_server(debug=True, use_reloader=False)
If df1 Visit column has value more than 1, then I would like to annotate subplots with arrow to articulate reading. To do so, I wrote the followings cript in update_bar_charts function, but it did not compile.
def update_bar_chart(value,slider_range):
low, high = slider_range
df1 = df.query("ID == @value & TIMEINTERVAL > @low & TIMEINTERVAL < @high").copy()
if df1.shape[0] != 0:
fig = px.scatter(df1, x="DATE_TIME", y=["SBP","DBP"],
hover_data=['TIMEINTERVAL'],facet_col='VISIT',
facet_col_wrap=2,
symbol='MODE')
fig.update_xaxes(matches= None, showticklabels=True)
if df1.VISIT!=1:
fig.add_annotation(
xref="x domain",
yref="y domain",
# The arrow head will be 25% along the x axis, starting from the left
x=0.25,
# The arrow head will be 40% along the y axis, starting from the bottom
y=0.4,
arrowhead=2,
)
return fig
else:
return dash.no_update
app.run_server(debug=True, use_reloader=False)
Whan I want to achieve is:
How can I add those arrows to make reading the plots easier? Number of arrows should change dynamically because each ID has different number of visits.


