0

I am working on a dash app, here is my code:

import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go

blue = '#6683f3'
orange = '#ff9266'
grey = '#e0e1f5'
black = '#212121'

app = dash.Dash()

app.layout = html.Div([html.Div([dcc.RadioItems(id = 'radio-item',
                                                options = [dict(label = 'squared',
                                                                value = '2'),
                                                           dict(label = 'cubed',
                                                                value = '3')],
                                                value = '2',
                                                labelStyle = {'display': 'block'})]),

                       html.Div(dcc.Graph(id = 'graph',
                                          figure = dict(data = [],
                                                        layout = go.Layout(plot_bgcolor = black)),
                                          style = dict(height = 1000)))])


@app.callback(Output('graph', 'figure'),
              [Input('radio-item', 'value')])
def update_graph(value):

    x = np.linspace(0, 10, 100)
    y = np.linspace(0, 10, 100)
    XX, YY = np.meshgrid(x, y)

    Z1 = XX ** int(value) * YY
    Z2 = XX ** int(value) / YY

    data = [go.Contour(z = Z1,
                       name = f'Z1',
                       zmin = 0,
                       zmax = 100,
                       contours_coloring = 'lines',
                       line_width = 2,
                       showscale = False,
                       showlegend = True,
                       visible = True,
                       colorscale = [[0, orange], [1, orange]],
                       ncontours = 21,
                       contours = dict(showlabels = True,
                                       labelformat = '.0f')),

            go.Contour(z = Z2,
                       name = f'Z2',
                       zmin = 0,
                       zmax = 100,
                       contours_coloring = 'lines',
                       line_width = 2,
                       showscale = False,
                       showlegend = True,
                       visible = True,
                       colorscale = [[0, blue], [1, blue]],
                       ncontours = 21,
                       contours = dict(showlabels = True,
                                       labelformat = '.0f'))]

    layout = go.Layout(plot_bgcolor = black,
                       hovermode = 'x unified')

    figure = go.Figure(data = data, layout = layout)

    figure.update_xaxes(title_text = 'X',
                        linewidth = 1,
                        nticks = 11,
                        gridwidth = 0.5,
                        gridcolor = grey,
                        tickformat = '.0f')

    figure.update_yaxes(title_text = 'Y',
                        linewidth = 1,
                        nticks = 11,
                        gridwidth = 0.5,
                        gridcolor = grey,
                        tickformat = '.0f')

    figure.update_layout(legend = dict(itemsizing = 'constant'))

    return figure


if __name__ == "__main__":
    app.run_server()

This code produces a graph and a RadioItems with two options. The content of the graph is updated accordingly to the RadioItems selected option through the update_graph function. So far so good.
The problem araises when I zoom/pan the graph and then I change the RadioItems option: the graph is correctly updated but it loses the zoom/pan I made before. Same issue if I show/hide one of the two traces and then I change the RadioItems option: the graph is updated but the visualization option of the traces is resetted.
This behavior is due to the code I have: when a user changes the RadioItems option, it is called the function update_graph that resets the graph, so properties like pan/zoom or hide/show trace options are lost.
I want to freeze these visualization options so that, when a user pans/zooms and then he changes RadioItems option, the graph is correctly updates but it keeps the pan/zoom the user made before. The same for the trace hide/show option.
I think there is a way to save in a variable the current displayed area and in another variable the visibility of the traces and recall this variables inside the update_graph, but I do not know how to save and recall these properties.

Version info:

Python                  3.7.0
dash                    1.12.0
dash-core-components    1.10.0
dash-html-components    1.0.3
dash-renderer           1.4.1
plotly                  4.8.1

1 Answer 1

2

I believe what you are looking for is the uirevision property (for details, see the documentation). To keep zoom, pan etc., set this property when you update the figure, i.e.

fig['layout']['uirevision'] = 'something'

It doesn't matter what you set as the value (you can use a number, a string, etc.), it only matters that the value remains unchanged during subsequent updates (where you wan't to keep zoom, pan, etc.). Whenever you need to reset the view, change the value to something else, e.g.

fig['layout']['uirevision'] = 42
Sign up to request clarification or add additional context in comments.

1 Comment

Following your advice, I edited go.Layout by adding uirevision = 'value' as parameter. This allows me to freeze the graph as I want. But what if I have 2 RadioItems ('A' and 'B') and I want to freeze the visualization with respect to the first and not with respect to the last?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.