How to plot the initial figure and update it in the same callback, but in a sequence?

Hello,

Here is a part of my code for plotting and adding traces to the plot.

I have two chained dropdown menus. With the first one, I can select the CSV file and store it as a Jason dataframe, and accordingly the options for the second dropdown menu updates based on the column names of the CSV file.

Now, for plotting, I want to have an initial 3d scatter plot based on the initial dataframe. Then, I want to do some changes (based on the selection in the second dropdown menu) and add them to the initial plot.

However, in my current code, I need to select from both dropdown menus, and then the figure shows the initial state and the updated one together. I want to plot the initial scatterplot when I chose from the first dropdown menu, and then plot the updated parts when I selected from the second dropdown menu.

@callback(
    Output('graph3', 'figure'),
    Input('table', 'data'),
    Input('dropdown2', 'value'),
    Input('my_rangeslider', 'value'),
    #prevent_initial_call=True
)
def plot_trajectory(js_df, feature, ranges):
    if (feature is None) or (ranges == []):
        return dash.no_update
    else:
        dff = pd.read_json(js_df, orient='split')
        fig = go.Figure()
        fig.add_trace(go.Scatter3d(x=dff['EW'], y=dff['NS'], z=dff['length'], mode='markers', marker={'color': 'blue', 'size': 4}))

        df_sliced = pd.concat([dff[(dff[feature] > ranges[1])], dff[(dff[feature] < ranges[0])]])

        fig.add_trace(go.Scatter3d(x=df_sliced['EW'], y=df_sliced['NS'], z=df_sliced['length'], mode='markers', marker={'color': 'red', 'size': 6}))
        fig.update_layout(hovermode='closest', margin={'l': 0, 'r': 0, 't': 30, 'b': 0}, showlegend=False, template="plotly_dark"),
        fig.update_scenes(zaxis_autorange="reversed")
    return fig

Hello @Peyman,

You are testing to see if a selection has been made first, if not, then you are returning dash.no_update.

If you change that bit of the code to generate an unfiltered plot, it should work as expected.

@callback(
    Output('graph3', 'figure'),
    Input('table', 'data'),
    Input('dropdown2', 'value'),
    Input('my_rangeslider', 'value'),
    #prevent_initial_call=True
)
def plot_trajectory(js_df, feature, ranges):
    if (feature is None) and (ranges != []):
        return initial chart
    elif ranges == []:
         return dash.no_update
    else:
        dff = pd.read_json(js_df, orient='split')
        fig = go.Figure()
        fig.add_trace(go.Scatter3d(x=dff['EW'], y=dff['NS'], z=dff['length'], mode='markers', marker={'color': 'blue', 'size': 4}))

        df_sliced = pd.concat([dff[(dff[feature] > ranges[1])], dff[(dff[feature] < ranges[0])]])

        fig.add_trace(go.Scatter3d(x=df_sliced['EW'], y=df_sliced['NS'], z=df_sliced['length'], mode='markers', marker={'color': 'red', 'size': 6}))
        fig.update_layout(hovermode='closest', margin={'l': 0, 'r': 0, 't': 30, 'b': 0}, showlegend=False, template="plotly_dark"),
        fig.update_scenes(zaxis_autorange="reversed")
    return fig

Thank you @jinnyzor for your reply. what is the initial chart? I only have one chart id=graph3 to show the plots.

What ever it is supposed to be. I don’t know what that is. It’s what you want it to be.

Sorry, I didn’t quite get your suggestion.

I cannot see what your initial chart is… This would be the chart that first loads with your layout. Since I cannot see more of your code, that was just a placeholder for where you would put it.

There is no other graph. Maybe I have not clearly stated my problem.
I have multiple csv files. I can select the name of one file from the first dropdown menu. Then based on this selection the options for the second dropdown menu changes. I have done this part through another callback.

However, I want to also be able to plot one of the file’s columns when I select the file name through the first dropdown.
I can plot it in the other callback that I talked about (to change the options for the second dropdown and also plot it.

However, I want to do some changes to the same graph by the selection from the second dropdown. but when I am in the new callback (the one I have written in this post), If I want to modify the same plot, it gives me an error that the same figure can not be the output of two different callbacks.

In order to do that, where you update the graph, it would have to be in the same callback, that is correct.

You can use ctx to determine which path it needs to use to update the graph.

As alternative to @jinnyzor suggested solution, you could use the dash extensions Multiplexer Transform.

Thank you, I will look into this to figure it out. Thanks

Thanks, I will look into that to see how it works.