@nedned Thank you for your response. I didn’t like using my click-register either, but I had left it as a diagnostic tool.
If you cant reproduce the precise problem, can I ask what you see if you run the code? Not the hoverData not disappear on you?:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, State, Input
import plotly.graph_objs as go
import numpy as np
import re
app = dash.Dash()
app.config['suppress_callback_exceptions'] = True
#######################################################################################################################
app.layout = html.Div([
################################################################################
html.Div([
# TODO: figure out why html.A components not working/updating and put all of them in button-activated Div
dcc.Dropdown(id='material-dropdown'),
html.Button('Add Material', id='add-material-button', n_clicks=0),
html.Div(id='material-options-container'),
html.A(id='material-message-update'),
html.Button('Create Cell', id='cell-geometry-button', n_clicks=0),
html.Div(id='cell-geometry-config-container'),
html.A(id='click-register'),
]),
])
#######################################################################################################################
# Materials Interface
# Keep track of material names
materials_list = []
# Invoke material options
@app.callback(
Output('material-options-container', 'children'),
[Input('add-material-button', 'n_clicks')],)
def invoke_material_options(n_clicks):
if n_clicks == 0:
return []
if n_clicks > 0:
options = html.Div([dcc.Input(id='material-name', placeholder='Enter Material Name'),
dcc.Input(id='material-density', placeholder='Enter Material Density', type='number'),
dcc.Input(id='material-temperature', placeholder='Enter Material Temperature', type='number'),
html.Button('Submit Material', id='submit-material-button', n_clicks=0),
html.Br()
])
return options
# Submit material to model
@app.callback(
Output('material-dropdown', 'options'),
[Input('submit-material-button', 'n_clicks')],
[State('material-name', 'value'),
State('material-density', 'value'),
State('material-temperature', 'value'),
State('material-dropdown', 'options')])
def submit_material(n_clicks, material_name, material_density, material_temperature, material_options):
if n_clicks > 0:
if material_options is not None:
material_options.append({'label': material_name, 'value': len(material_options)+1})
materials_list.append(material_name)
if material_options is None:
material_options = [{'label': material_name, 'value': 0}]
materials_list.append(material_name)
n_clicks = 0
return material_options
#######################################################################################################################
# Geometry Interface
# Initiate cell geometry config with button
@app.callback(
Output('cell-geometry-config-container', 'children'),
[Input('cell-geometry-button', 'n_clicks')],)
def invoke_cell_geometry_options(n_clicks):
if n_clicks > 0:
options = html.Div([dcc.Graph(id='planes-graph'),
# TODO: decide whether different material dropdown should be added for geometry section
dcc.Input(id='planes-list', placeholder='Enter list of radial planes (comma separated)',
type="text"),
html.Button('Fill Region', id='fill-region-button', n_clicks=0),
html.Br(),
])
return options
# Fill Region
@app.callback(
Output('planes-graph', 'figure'),
[Input('planes-list', 'value'),
Input('fill-region-button', 'n_clicks')],
[State('material-dropdown', 'value'),
State('planes-graph', 'clickData')]
)
def fill_region(planes, n_clicks, selected_material, clickData):
if planes is None:
return {}
else:
planes = [float(plane) for plane in planes.split(',')]
planes.sort()
edge = planes[-1]
x = np.linspace(-edge, edge, 250)
y = np.linspace(-edge, edge, 250)
regions = []
cell_hover = []
# Normal Display
for i in x:
row = []
text_row = []
for j in y:
if np.sqrt(i ** 2 + j ** 2) < planes[0]:
row.append(7) # <- Arbitrary number to adjust color
text_row.append('Region 1')
if np.sqrt(i ** 2 + j ** 2) > planes[-1]:
row.append(5) # <- Arbitrary number to adjust color
text_row.append('Region {}'.format(len(planes) + 1))
for k in range(len(planes) - 1):
if planes[k] < np.sqrt(i ** 2 + j ** 2) < planes[k + 1]:
row.append(k * 3) # <- Arbitrary number to adjust color
text_row.append('Region {}'.format(k + 2))
regions.append(row)
cell_hover.append(text_row)
# Initialize region
if clickData is not None:
if 'points' in clickData:
point = clickData['points'][0]
if 'text' in point:
region = int(re.search(r'\d+', point['text']).group())
if 'x' in point:
click_x = point['x']
if 'y' in point:
click_y = point['y']
if n_clicks > 0:
new_hover = []
# Change graph on Click # TODO: Figure out why new text wont show up
if 0 < np.sqrt(click_x ** 2 + click_y ** 2) < planes[0]:
for row_ in cell_hover:
for text in row_:
new_hover.append(text.replace('Region 1', '{} Region'.format(materials_list[selected_material])))
if np.sqrt(click_x ** 2 + click_y ** 2) > planes[-1]:
for row_ in cell_hover:
for text in row_:
new_hover.append(text.replace('Region {}'.format(len(planes) + 1),
'{} Region'.format(materials_list[selected_material])))
for k in range(len(planes) - 1):
if planes[k] < np.sqrt(click_x ** 2 + click_y ** 2) < planes[k + 1]:
for row_ in cell_hover:
for text in row_:
new_hover.append(text.replace('Region {}'.format(k + 2),
'{} Region'.format(materials_list[selected_material])))
cell_hover = new_hover
n_clicks = 0
######################################################
heatmap = go.Heatmap(z=regions, x=x, y=y, hoverinfo='x+y+text', text=cell_hover, opacity=0.5, showscale=False)
data = [heatmap]
shapes = []
for plane in planes:
shape = {
'type': 'circle',
'x0': -plane,
'y0': -plane,
'x1': plane,
'y1': plane,
'line': {
'width': 4,
},
'opacity': 1
}
shapes.append(shape)
layout = dict(title='Cell Region Depiction',
height=1000,
width=1000,
shapes=shapes)
figure = dict(data=data, layout=layout)
return figure
if __name__ == '__main__':
app.run_server()
Also the hover data now disappears like it does in my full code for some reason.