Hi @jhupiterz ,
Thank you for the example code. I followed your instruction, and wrote a similar code for my case, but I still have some problems:
-
In the function display_selected_data, I can remove selected data points from my list MJD and DM. However, I would like to remove more data points. I adjusted the code ‘MJD_filtered = list(set(MJD) - set(x))’ to ‘MJD = list(set(MJD) - set(x))’, but got an error ‘cannot access local variable ‘MJD’ where it is not associated with a value’. I am wondering if you know how to solve this.
-
I also added a function display_hover so that when I hover the mouse over a data point its associated image file can pop up. However, that means every time I delete some data points, I also need to update the list of paths to the image files. I am wondering if you know how to keep the three lists, i.e. MJD, DM and cand_plots, consistent throughout the process of deleting data points.
Please see below my code:
import plotly.express as px
from dash import Dash, dcc, html, Input, Output, no_update, callback
import plotly.graph_objects as go
import base64
import json
fig = go.Figure(data=[go.Scatter(x=MJD, y=DM, mode="markers",)])
fig.update_traces(hoverinfo="none", hovertemplate=None)
fig.update_layout(xaxis=dict(title='MJD'),yaxis=dict(title='DM'))
app = Dash(__name__)
app.layout = html.Div([dcc.Graph(id="graph-basic-2", figure=fig, clear_on_unhover=True),
dcc.Tooltip(id="graph-tooltip"),
dcc.Store(id= 'data-selection'),
html.Button('Reset plot', id='reset-button', n_clicks=0)
])
@app.callback(Output('graph-basic-2', 'figure'),
Output('reset-button', 'n_clicks'),
Input('reset-button', 'n_clicks'),
Input('graph-basic-2', 'selectedData'),
prevent_initial_call = True
)
def display_selected_data(n_clicks, selectedData):
if n_clicks > 0:
fig = go.Figure(data=[go.Scatter(x=MJD, y=DM, mode="markers",)])
return [fig, 0]
else:
x = [x["x"] for x in selectedData["points"]]
y = [x["y"] for x in selectedData["points"]]
MJD_filtered = list(set(MJD) - set(x))
DM_filtered = list(set(DM) - set(y))
fig = go.Figure(data=[go.Scatter(x=MJD_filtered, y=DM_filtered, mode="markers",)])
return [fig, 0]
@callback(
Output("graph-tooltip", "show"),
Output("graph-tooltip", "bbox"),
Output("graph-tooltip", "children"),
Input("graph-basic-2", "hoverData"),
)
def display_hover(hoverData):
if hoverData is None:
return False, no_update, no_update
pt = hoverData["points"][0]
bbox = pt["bbox"]
num = pt["pointNumber"]
with open(cand_plots[num], "rb") as image_file:
img_data = base64.b64encode(image_file.read())
img_data = img_data.decode()
img_data = "{}{}".format("data:image/jpg;base64, ", img_data)
children = [
html.Div([
html.Img(src=img_data, style={"width": "100%"}),
], style={'width': '200px', 'white-space': 'normal'})
]
return True, bbox, children
app.run(debug=True)