So I have this dash app where I want to display a png image based on the user's input. It works, but the problem is every time the user makes a selection the image is shown on top of the previous image. I want to somehow clear the previous image so it only shows the most recently selected image.
In app.layout
I have:
app.layout = html.Div(children=[
html.H4(children='Spider Plot'),
dcc.Dropdown(id="select_group",
options=[
{"label": "Student", "value": 'Student'},
{"label": "Parent", "value": 'Parent'},
{"label": "Both", "value": 'Both'}],
multi=False,
value="Student",
style={'width': "40%"}
),
html.Div(id="spider_img", children=[]),
])
And for the callback I have:
@app.callback(
Output(component_id='spider_img', component_property='children'),
Input(component_id='select_group', component_property='value')
)
def update_graph(group):
key = (2002, group)
A = perm_to_series(Ds.loc[key,'D'],Ds.loc[key,'details_fixed_cont_x_minimize']['perm'],'Closest')
B = perm_to_series(Ds.loc[key,'D'],Ds.loc[key,'details_fixed_cont_x_maximize']['perm'],'Farthest')
pyrankability.plot.spider2(A,B,file='/tmp/spider3.png')
return html_image(open('/tmp/spider3.png','rb').read())
I the function html_image
is defined by me because apparently this is the way to insert static png images in dash.
def html_image(img_bytes):
encoding = b64encode(img_bytes).decode()
img_b64 = "data:image/png;base64," + encoding
return html.Img(src=img_b64, style={'height': '30%', 'width': '30%'})
This does seem like a kind of hacky way to do things, and if there is a better way let me know, but this is the only thing that worked for me. So when looking for how to clear previous output I thought it would be simple, but I didn't really find much. There are posts that show how to clear a plot by clicking on it such as here but that's not what I want, I just want the previous image to be cleared so they don't overlap. How can I clear my component so it displays properly?
Edit: Here is the updated code using html.Img
and component_property='src'
:
app.layout = html.Div(children=[
html.H4(children='Spider Plot'),
dcc.Dropdown(id="select_group",
options=[
{"label": "Student", "value": 'Student'},
{"label": "Parent", "value": 'Parent'},
{"label": "Both", "value": 'Both'}],
multi=False,
value="Student",
style={'width': "40%"}
),
html.Img(id="spider_img", style={'height': '30%', 'width': '30%'})
])
@app.callback(
Output(component_id='spider_img', component_property='src'),
Input(component_id='select_group', component_property='value')
)
def update_graph(group):
key = (2002, group)
A = perm_to_series(Ds.loc[key,'D'],Ds.loc[key,'details_fixed_cont_x_minimize']['perm'],'Closest')
B = perm_to_series(Ds.loc[key,'D'],Ds.loc[key,'details_fixed_cont_x_maximize']['perm'],'Farthest')
pyrankability.plot.spider2(A,B,file='/tmp/spider3.png')
img = open('/tmp/spider3.png','rb').read()
return "data:image/png;base64," + base64.b64encode(img).decode()