How to register two click events in a row on the same marker
Question:
In a Dash app, I would like to toggle the values of a boolean array when markers in a scatterplot are clicked. If I click the same marker twice in a row, I would like to toggle that value twice, but the second click is not registered. I can only click on some other marker.
Here is a minimal working example:
from dash import Dash, html, dcc
from dash.dependencies import Input, Output
from plotly import graph_objects as go
bools = [False, False, False]
app = Dash(__name__)
fig = go.Figure(go.Scatter(x=[0, 1, 2], y = [2, 1, 2]))
graph = dcc.Graph(id = 'graph', figure = fig)
app.layout = html.Div(graph)
@app.callback(
Output('graph', 'figure'),
Input('graph', 'clickData')
)
def toggle(clickData):
global bools
n_marker = clickData['points'][0]['pointNumber']
bools[n_marker] = not bools[n_marker]
print(bools)
app.run_server(debug = True)
This seems related to this old question using plotly in R, but I wasn’t able to figure out how to use the answers there in python + dash.
Answers:
Following the discussion here, the solution is to reset the Output in the callback to None
, as follows:
import dash
import plotly.express as px
from jupyter_dash import JupyterDash
from dash import Dash,Input, Output, html
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
app = Dash(__name__)
app.layout = dash.html.Div(
[dash.dcc.Graph(id="graph", figure=fig)]
)
@app.callback(
Output("graph", "clickData"),
Input("graph", "clickData"),
prevent_initial_call = True
)
def click(clickData):
x = clickData["points"][0]['x']
y = clickData["points"][0]['x']
print(f"point is located in x={x} and y={y}")
return None
app.run_server(debug=True, use_reloader=False)
Output
In a Dash app, I would like to toggle the values of a boolean array when markers in a scatterplot are clicked. If I click the same marker twice in a row, I would like to toggle that value twice, but the second click is not registered. I can only click on some other marker.
Here is a minimal working example:
from dash import Dash, html, dcc
from dash.dependencies import Input, Output
from plotly import graph_objects as go
bools = [False, False, False]
app = Dash(__name__)
fig = go.Figure(go.Scatter(x=[0, 1, 2], y = [2, 1, 2]))
graph = dcc.Graph(id = 'graph', figure = fig)
app.layout = html.Div(graph)
@app.callback(
Output('graph', 'figure'),
Input('graph', 'clickData')
)
def toggle(clickData):
global bools
n_marker = clickData['points'][0]['pointNumber']
bools[n_marker] = not bools[n_marker]
print(bools)
app.run_server(debug = True)
This seems related to this old question using plotly in R, but I wasn’t able to figure out how to use the answers there in python + dash.
Following the discussion here, the solution is to reset the Output in the callback to None
, as follows:
import dash
import plotly.express as px
from jupyter_dash import JupyterDash
from dash import Dash,Input, Output, html
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
app = Dash(__name__)
app.layout = dash.html.Div(
[dash.dcc.Graph(id="graph", figure=fig)]
)
@app.callback(
Output("graph", "clickData"),
Input("graph", "clickData"),
prevent_initial_call = True
)
def click(clickData):
x = clickData["points"][0]['x']
y = clickData["points"][0]['x']
print(f"point is located in x={x} and y={y}")
return None
app.run_server(debug=True, use_reloader=False)
Output