Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Undesired behaviour (interaction?) with two dcc.Store #778

Closed
emmanuelle opened this issue Mar 17, 2020 · 1 comment · Fixed by #792
Closed

Undesired behaviour (interaction?) with two dcc.Store #778

emmanuelle opened this issue Mar 17, 2020 · 1 comment · Fixed by #792

Comments

@emmanuelle
Copy link
Contributor

The issue originates from https://community.plot.ly/t/components-triggered-by-table-not-updating/36288/4
With

import dash
import dash_table
import pandas as pd

import dash_html_components as html
import dash_core_components as dcc

from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import plotly.graph_objs as go

app = dash.Dash(__name__)
server = app.server

app.layout = html.Div(children=[
	dash_table.DataTable(
	id='table-data',
	data=[{'x':'test', 'graph': 0}],
	columns=[
		{'id': 'x', 'name': 'x', 'editable':False},
		{'id': 'graph', 'name': 'graph', 'presentation': 'dropdown', 'editable':True}],
	dropdown={
		'graph': {
			'options': [
				{'label': 'Do not show', 'value': 0x0},
				{'label': 'Plot 1', 'value': 1},
				{'label': 'Plot 2', 'value': 2}],
			},
		},
	row_deletable=False,
	editable=True,
	),
	dcc.Store(id='g1buffer', storage_type='memory'),
	dcc.Store(id='g2buffer', storage_type='memory'),
	dcc.Graph(id='plot-graph1'),
	dcc.Graph(id='plot-graph2'),
])


@app.callback(
	Output('plot-graph1', 'figure'),
	[Input('g1buffer', 'data')],
)
def update_graph1(data):
	if data is None:
		raise PreventUpdate
	return data

@app.callback(
	Output('plot-graph2', 'figure'),
	[Input('g2buffer', 'data')],
)
def update_graph2(data):
	if data is None:
		raise PreventUpdate
	return data

@app.callback(
	[
		Output('g1buffer', 'data'),
		Output('g2buffer', 'data'),
	],
	[Input('table-data', 'data')],
)
def update_on_table(table_data):
	data = go.Scatter(
				x=[1,2,3,4],
				y=[2,5,1,3],
				)
	g1 = {}
	g2 = {}
	if table_data[0]['graph'] == 1:
		g1 = {'data': [data]}
	if table_data[0]['graph'] == 2:
		g2 = {'data': [data]}
	return g1, g2

if __name__ == '__main__':
    app.run_server(debug=True)

the dropdown does not update the figures as expected (sometimes plot 1 does not show up as it should). Modifying the layout to have a single dcc.Store seems to solve the problem (see below). Could there be undesired interactions between the two dcc.Store?

import dash
import dash_table
import pandas as pd

import dash_html_components as html
import dash_core_components as dcc

from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import plotly.graph_objs as go

app = dash.Dash(__name__)
server = app.server



app.layout = html.Div(children=[
	dash_table.DataTable(
	id='table-data',
	data=[{'x':'test', 'graph': 0}],
	columns=[
		{'id': 'x', 'name': 'x', 'editable':False},
		{'id': 'graph', 'name': 'graph', 'presentation': 'dropdown', 'editable':True}],
	dropdown={
		'graph': {
			'options': [
				{'label': 'Do not show', 'value': 0x0},
				{'label': 'Plot 1', 'value': 1},
				{'label': 'Plot 2', 'value': 2}],
			},
		},
	editable=True,
	),
	dcc.Store(id='gbuffer'),
	dcc.Graph(id='plot-graph1'),
	dcc.Graph(id='plot-graph2'),
])


@app.callback(
	Output('plot-graph1', 'figure'),
	[Input('gbuffer', 'data')],
)
def update_graph1(data):
    print('update_graph1', data)
    if data is None:
        raise PreventUpdate
    return data[0]

@app.callback(
	Output('plot-graph2', 'figure'),
	[Input('gbuffer', 'data')],
)
def update_graph2(data):
    print('update_graph2', data)
    if data is None:
        raise PreventUpdate
    return data[1]

@app.callback(
	 Output('gbuffer', 'data'),
	[Input('table-data', 'data')],
)
def update_on_table(table_data):
    data = go.Scatter(
                            x=[1,2,3,4],
                            y=[2,5,1,3],
                            )
    g1 = {}
    g2 = {}
    if table_data[0]['graph'] == 1:
        g1 = {'data': [go.Scatter(x=[1, 2], y=[1, 2])]}
    if table_data[0]['graph'] == 2:
        g2 = {'data': [go.Scatter(x=[1, 3], y=[2, 3])]}
    return [g1, g2]

if __name__ == '__main__':
    app.run_server(debug=True)
@alexcjohnson
Copy link
Collaborator

I'm not sure whether it's due to callback fixes in dash v1.11, fixes since then due out in v1.12, or Store fixes in #792, but using the current dev branch of Dash and the store-robustify branch here this issue appears to be fixed. I'll tag it to #792 anyway just so there's a PR to close it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants