so today, I’m trying to create a simple dahsboard with data from multiple dataframes. I use the dropdown to select the dataframe to show in the plot. However, when I run this code, I got callback error in the web page says
Callback error updating loglog.figure Traceback (most recent call last): File "C:UsersnaharAppDataLocalTemp/ipykernel_1556/982666652.py", line 63, in build_graph TypeError: string indices must be integers
I don’t understand why this occurs, here is the code
logs = ['CALI','RDEP','GR','RHOB','NPHI','SP','DTC'] colors = ['black','firebrick','green','mediumaquamarine','royalblue','goldenrod','lightcoral'] log_cols = np.arange(1,8) app = dash.Dash(__name__, external_stylesheets=[dbc.themes.SANDSTONE], meta_tags=[ {"name": "viewport", "content": "width=device-width, initial-scale=1"} ]) server = app.server app.config.suppress_callback_exceptions = True app.layout = dbc.Container([ dbc.Row([ dbc.Col(html.H1('FORCE 2020 Well Log Challange Dashboard', className='text-center mb-4'), width=12) ]), dbc.Row([ dbc.Col([ dcc.Dropdown(id='droplog', options=[ {'label':'15/9-13','value':'well1'}, {'label':'15/9-15','value':'well2'}, {'label':'15/9-17','value':'well3'}, {'label':'16/1-2','value':'well4'}, {'label':'16/1-6 A','value':'well5'}, {'label':'16/10-1','value':'well6'}, {'label':'16/10-2','value':'well7'}, {'label':'16/10-3','value':'well8'}, {'label':'16/10-5','value':'well9'}, {'label':'16/11-1 ST3','value':'well10'}, {'label':'16/2-11 A','value':'well11'}, {'label':'16/2-16','value':'well12'} ], multi=False, value='well1'), dcc.Graph(id='loglog',figure={}) ]) ]), dbc.Row([ ]) ]) @app.callback( Output(component_id='loglog',component_property='figure'), [Input(component_id='droplog',component_property='value')] ) def build_graph(plot_chosen): logplot = make_subplots(rows=1, cols=len(logs), shared_yaxes=True) for i in range (len(logs)): if i == 1: logplot.add_trace(go.Scatter(x=plot_chosen[logs[i]], y=plot_chosen['DEPTH_MD'], name=logs[i], line_color=colors[i]),row=1, col=log_cols[i]) logplot.update_xaxes(type='log',row=1, col=log_cols[i], title_text=logs[i], tickfont_size=12, linecolor='#585858') else: logplot.add_trace(go.Scatter(x=plot_chosen[logs[i]], y=plot_chosen['DEPTH_MD'], name=logs[i], line_color=colors[i]),row=1, col=log_cols[i]) logplot.update_xaxes(col=log_cols[i], title_text=logs[i], linecolor='#585858') logplot.update_xaxes(showline=True, linewidth=2, linecolor='black', mirror=True, ticks='inside', tickangle= 0) logplot.update_yaxes(tickmode='linear', tick0=0,dtick=250, showline=True, linewidth=2, linecolor='black', mirror=True, ticks='outside') logplot.update_yaxes(row=1, col=1, autorange='reversed') logplot.update_layout(height=750, width=1200, showlegend=False) logplot.update_layout(plot_bgcolor = "rgba(0,0,0,0)", paper_bgcolor = "rgba(0,0,0,0)") return logplot if __name__=='__main__': app.run_server(debug=True,use_reloader=False)
and the input data used is in the form of many dataframes, one of which is like this for well 1
I tried to run defined function only, which build_graph, and it worked like a charm. The result of figure is shown here
Advertisement
Answer
I think I know what the problem is: the variable plot_chosen
which is the argument in the function build_graph
is a string. As a result you can not type y=plot_chosen['DEPTH_MD']
. Although after choosing 15/9-13 on the Dropdown menu it has a value of well1
, it does not represent the dataframe but a simple string. Try creating for example a dictionary with the dataframes
dataframes = {'well1': well1, 'well2': well2, ...}
and then choose the appropriate DataFrame from the dictionary.
So for example when the user chooses 15/9-13 on the dropdown you will get plot_chosen=’well1′ and you can simply get the dataframe well1
by using dataframes[plot_chosen]
.