Hi, I am trying to modify the code in the ‘Update Graphs on Hover’ section here: Part 3. Interactive Graphing and Crossfiltering | Dash for Python Documentation | Plotly. However, the hover data displayed on my plot, as well as the customdata
do not match what was plotted. I strongly feel there must be some indexing going on that I do not understand. The blob_df
generated should look like this:
train_val
column is filled with str
. However, hovering over the data we can see that the ‘train_val’ hover data seems to be populated by int
.You can observe the same thing if you monitor my_demo_log.txt
while hovering over various points – the X, y values do not even match. What am I missing that will get my hover and custom data index properly?
Thank you
from dash import Dash, html, dcc, Input, Output
import pandas as pd
import plotly.express as px
import joblib as jb
import numpy as np
from sklearn.datasets import make_blobs
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = Dash(__name__, external_stylesheets=external_stylesheets)
np.random.seed(42)
b = make_blobs(n_samples = 200, random_state=42)
blob_df = pd.DataFrame(b[0], columns = ['X', 'y'])
blob_df['class'] = b[1]
blob_df['site'] = np.random.randint(0, 1, len(blob_df))
blob_df.loc[:150, 'train_val'] = 'train'
blob_df.loc[150:, 'train_val'] = 'val'
symbol_color_cols = []
for i in range(3):
new_col = f'predicted_class_v{i}'
blob_df[new_col] = blob_df['class'].copy()
alter_idx = np.random.randint(0, 200, 50)
alter_vals = np.random.randint(0, 2, 50)
blob_df.loc[alter_idx, new_col] = alter_vals
symbol_color_cols.append(new_col)
symbol_color_cols = symbol_color_cols + ['class']
blob_df['info0'] = np.arange(0, 200, 1)
blob_df['info2'] = (blob_df['info0']) * 10
app.layout = html.Div([
html.Div([
dcc.RadioItems(
symbol_color_cols,
symbol_color_cols[0],
id='symbol_col',
labelStyle={'display': 'inline-block', 'marginTop': '5px'}
)
],
style={'width': '49%', 'display': 'inline-block'}),
html.Div([
dcc.RadioItems(
symbol_color_cols,
symbol_color_cols[1],
id='color_col',
labelStyle={'display': 'inline-block', 'marginTop': '5px'}
)
],
style={'width': '49%', 'display': 'inline-block', 'float':'right'}),
html.Div([
dcc.Graph(
id='umap-scatter',
#hoverData={'points': [{'customdata': None}]}
)
], #style={'width': '100%', 'height':'75%', 'display': 'inline-block', 'padding': '0 20'}),
style={'width': '100%', 'display': 'inline-block', }),
html.Div([
dcc.Graph(
id='dummy-div',
#hoverData={'points': [{'customdata': 'Japan'}]}
)
], #style={'width': '100%', 'height':'75%', 'display': 'inline-block', 'padding': '0 20'}),
style={'width': '100%', 'display': 'inline-block', }),
])
@app.callback(
Output('umap-scatter', 'figure'),
Input('symbol_col', 'value'),
Input('color_col', 'value'))
def update_umap_scatter(symbol_col, color_col):
#plot_me = blob_df.reset_index(drop = True)
#hover_dat = plot_me.copy()
fig = px.scatter(data_frame=blob_df,
color_discrete_map={'0':'deepskyblue', '1':'olive', '2':'coral',},
symbol_map={'0':'circle', '1':'hourglass', '2':'star'},
x ='X',
facet_row='site', facet_col='train_val', y = 'y',
color = color_col, symbol=symbol_col, hover_data=list(blob_df.columns)
)
fig.update_traces(customdata=blob_df.copy())
#fig.update_traces(hover_data=list(hover_dat.columns))
#fig.update_traces(hovertemplate = f'hover_data_0=%{customdata[0]}<br>label=%{customdata[1]}<extra></extra>')
fig.update_layout(height=800,
legend=dict(
yanchor="top",
y=0.99,
xanchor="left",
x=-.1
))
return fig
@app.callback(
Output('dummy-div', 'figure'),
Input('umap-scatter', 'hoverData'),
)
def log_hoverdata(hoverData, ):
hdp = hoverData['points']
with open('my_demo_log.txt', 'w') as f:
f.write(str(hdp))
if __name__ == '__main__':
app.run_server(debug=True)