Hi guys,
I am trying to implement an interface where click event on any plot highlights the same data point on another plots. Here is an example:
import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import numpy as np
app = dash.Dash()
app.css.append_css({'external_url': 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css'})
x = np.random.uniform(size=10)
y = np.random.uniform(size=10)
z = np.random.uniform(size=10)
app.layout = html.Div([
html.Div([
dcc.Graph(
id='g1',
figure=dict(
data = [go.Scatter(x=x,y=y,mode='markers',showlegend=False)],
layout = go.Layout(
xaxis = dict(title = 'X'),
yaxis = dict(title = 'Y'),
hovermode = 'closest'))
)],
className="col-4"),
html.Div([
dcc.Graph(
id='g2',
figure=dict(
data = [go.Scatter(x=y,y=z,mode='markers',showlegend=False)],
layout = go.Layout(
xaxis = dict(title = 'Y'),
yaxis = dict(title = 'Z'),
hovermode = 'closest'))
)],
className="col-4"),
html.Div([
dcc.Graph(
id='g3',
figure=dict(
data = [go.Scatter(x=x,y=z,mode='markers',showlegend=False)],
layout = go.Layout(
xaxis = dict(title = 'X'),
yaxis = dict(title = 'Z'),
hovermode = 'closest'))
)],
className="col-4")
],className="row")
@app.callback(
Output('g1', 'figure'),
[Input('g1', 'clickData'), Input('g2', 'clickData'), Input('g3', 'clickData')],
state = [State('g1', 'figure')])
def highligh_points_g1(clickData1, clickData2, clickData3, figure):
# for temporal usage
clickData = clickData3
if clickData != None:
point_id = clickData['points'][0]['pointNumber']
point_highlight = go.Scatter(
x=[x[point_id]],
y=[y[point_id]],
mode='markers',
showlegend=False,
marker=go.Marker(size=10, line={'width': 1}, color='black', symbol='circle-open')
)
if len(figure['data']) == 2:
figure['data'][1] = point_highlight
else:
figure['data'].append(point_highlight)
return figure
@app.callback(
Output('g2', 'figure'),
[Input('g1', 'clickData'), Input('g2', 'clickData'), Input('g3', 'clickData')],
state = [State('g2', 'figure')])
def highligh_points_g2(clickData1, clickData2, clickData3, figure):
# ....
@app.callback(
Output('g3', 'figure'),
[Input('g1', 'clickData'), Input('g2', 'clickData'), Input('g3', 'clickData')],
state = [State('g3', 'figure')])
def highligh_points_g3(clickData1, clickData2, clickData3, figure):
# ...
if __name__ == '__main__':
app.run_server(debug=True)
In that example, I use events from third panel only but I would like to be able to handle click events come from any plot. The problem is that clickData is not cleaned like hoverData in case of option clear_on_unhover=True
and I cannot choose the last handled clickData.
Does anyone idea how to implement such behavior?
With best regards,
Ivan