Thanks for your answer! I am working with callbacks. However, I am not sure how I can combine plotting data with the series of background images. Do you have any advice for me on how to do that?
This is my current code (it displays the data and image information next to each other but not combined in one graphâŚ
from dash import Dash, html, dcc, Input, Output
import pandas as pd
import plotly.express as px
import cv2
import glob
import numpy as np
external_stylesheets = [âhttps://codepen.io/chriddyp/pen/bWLwgP.cssâ]
app = Dash(name, external_stylesheets=external_stylesheets)
df = pd.read_csv(âinfo.csvâ, delimiter=â;â)
read images
file = âplots/*.pngâ
glob.glob(file)
img=
for i in range(20):
image = â{}.pngâ.format(i)
img.append(cv2.imread(image))
img = np.asarray(img, dtype=np.uint8)
fig = px.imshow(img,origin=âupperâ, animation_frame=0, binary_string=True, labels=dict(animation_frame=âsliceâ))
fig.update_layout(width=500, height=500)
pass just the function name to apply
app.layout = html.Div([
html.Div([
html.Div([
dcc.Dropdown(
df['horizon'].unique(), # used to be inficator name
2,
id='crossfilter-xaxis-column',
),
dcc.RadioItems(
['Linear', 'Log'],
'Linear',
id='crossfilter-xaxis-type',
labelStyle={'display': 'inline-block', 'marginTop': '5px'}
)
],
style={'width': '49%', 'display': 'inline-block'}),
html.Div([
dcc.Dropdown(
df['dt'].unique(),
0.1,
id='crossfilter-yaxis-column'
),
dcc.RadioItems(
['Linear', 'Log'],
'Linear',
id='crossfilter-yaxis-type',
labelStyle={'display': 'inline-block', 'marginTop': '5px'}
)
], style={'width': '49%', 'float': 'right', 'display': 'inline-block'})
], style={
'padding': '10px 5px'
}),
html.Div([
dcc.Graph(
id='crossfilter-indicator-scatter',
hoverData={'points': [{'customdata': '0'}]}
)
], style={'width': '49%', 'display': 'inline-block', 'padding': '0 20'}),
html.Div([
dcc.Graph(figure=fig),
], style={'display': 'inline-block', 'width': '45%'}),
html.Div(dcc.Slider(
df['time_step'].min(),
df['time_step'].max(),
step=None,
id='crossfilter-time_step--slider',
value=df['time_step'].max(),
marks={str(time_step): str(time_step) for time_step in df['time_step'].unique()}
), style={'width': '49%', 'padding': '0px 20px 20px 20px'}),
html.Div([
dcc.Graph(id='x-time-series'),
dcc.Graph(id='y-time-series'),
], style={'display': 'inline-block', 'width': '49%'}),
])
@app.callback(
Output(âcrossfilter-indicator-scatterâ, âfigureâ),
Input(âcrossfilter-xaxis-columnâ, âvalueâ),
Input(âcrossfilter-yaxis-columnâ, âvalueâ),
Input(âcrossfilter-xaxis-typeâ, âvalueâ),
Input(âcrossfilter-yaxis-typeâ, âvalueâ),
Input(âcrossfilter-time_stepâsliderâ, âvalueâ))
def update_graph(xaxis_column_name, yaxis_column_name,
xaxis_type, yaxis_type,
time_step_value):
dff = df[df[âtime_stepâ] == time_step_value]
fig = px.scatter(x=dff[dff['horizon'] == xaxis_column_name]['x_position_m'], # to be changed
y=dff[dff['dt'] == yaxis_column_name]['y_position_m']#, # to be changed
#hover_name = dff[dff['dt'] == yaxis_column_name]['trajectory_number']
)
fig.update_traces(customdata=dff[dff['dt'] == yaxis_column_name]['trajectory_number'])
fig.update_xaxes(title=xaxis_column_name, type='linear' if xaxis_type == 'Linear' else 'log')
fig.update_yaxes(title=yaxis_column_name, type='linear' if yaxis_type == 'Linear' else 'log')
fig.update_layout(margin={'l': 40, 'b': 40, 't': 10, 'r': 0}, hovermode='closest')
return fig
def create_time_series(dff, axis_type, title):
fig = px.scatter(dff, x='time_step', y='x_position_m') # to be changed
fig.update_traces(mode='lines+markers')
fig.update_xaxes(showgrid=False)
fig.update_yaxes(type='linear' if axis_type == 'Linear' else 'log')
fig.add_annotation(x=0, y=0.85, xanchor='left', yanchor='bottom',
xref='paper', yref='paper', showarrow=False, align='left',
text=title)
fig.update_layout(height=225, margin={'l': 20, 'b': 30, 'r': 10, 't': 10})
return fig
@app.callback(
Output(âx-time-seriesâ, âfigureâ),
Input(âcrossfilter-indicator-scatterâ, âhoverDataâ),
Input(âcrossfilter-xaxis-columnâ, âvalueâ),
Input(âcrossfilter-xaxis-typeâ, âvalueâ))
def update_y_timeseries(hoverData, xaxis_column_name, axis_type):
traj_name = hoverData[âpointsâ][0][âcustomdataâ]
dff = df[df[âtrajectory_numberâ] == traj_name]
dff = dff[dff[âhorizonâ] == xaxis_column_name]
title = â{}
{}â.format(traj_name, xaxis_column_name)
return create_time_series(dff, axis_type, title)
@app.callback(
Output(ây-time-seriesâ, âfigureâ),
Input(âcrossfilter-indicator-scatterâ, âhoverDataâ),
Input(âcrossfilter-yaxis-columnâ, âvalueâ),
Input(âcrossfilter-yaxis-typeâ, âvalueâ))
def update_x_timeseries(hoverData, yaxis_column_name, axis_type):
dff = df[df[âtrajectory_numberâ] == hoverData[âpointsâ][0][âcustomdataâ]]
dff = dff[dff[âdtâ] == yaxis_column_name]
return create_time_series(dff, axis_type, yaxis_column_name)
if name == âmainâ:
app.run_server(debug=True)