在 Dash 中清除回调中的组件
Clearing a Component on Callback in Dash
所以我有这个 dash 应用程序,我想在其中根据用户的输入显示 png 图像。它有效,但问题是每次用户进行选择时,图像都会显示在前一张图像的顶部。我想以某种方式清除之前的图像,以便它只显示最近选择的图像。
在app.layout
我有:
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=[]),
])
对于回调我有:
@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())
函数 html_image
是我定义的,因为显然这是在 dash 中插入静态 png 图像的方法。
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%'})
这似乎是一种做事的方式,如果有更好的方法请告诉我,但这是唯一对我有用的方法。所以在寻找如何清除以前的输出时,我认为这很简单,但我并没有找到太多。有些帖子显示如何通过单击清除图,例如 here 但这不是我想要的,我只希望清除之前的图像,这样它们就不会重叠。如何清除我的组件以使其正确显示?
编辑:这是使用 html.Img
和 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()
要更新现有图像,您应该在 app.layout
中使用 html.Img(...)
而不是 html.Div(..., children=[])
,并更新 component_property='src'
而不是 component_property='children'
许多工具可以将 image/file 保存在使用 io.BytesIO()
在内存中创建的 file-like
对象中
matplotlib
的示例
# plot something
plt.plot(...)
# create file-like object in memory
buffer_img = io.BytesIO()
# save in file-like object
plt.savefig(buffer_img, format='png')
# move to the beginning of buffer before reading (after writing)
buffer_img.seek(0)
# read from file-like object
img_bytes = buffer_img.read()
# create base64
img_encoded = "data:image/png;base64," + base64.b64encode(img_bytes).decode()
最少的工作代码
import dash
import dash_core_components as dcc
import dash_html_components as html
import base64
import io
import matplotlib.pyplot as plt
app = dash.Dash()
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(
dash.dependencies.Output(component_id='spider_img', component_property='src'),
dash.dependencies.Input(component_id='select_group', component_property='value')
)
def update_graph(group):
# plot
plt.clf()
plt.text(5, 5, group, size=20)
plt.xlim(0, 15)
plt.ylim(0, 10)
# create file-like object in memory
buffer_img = io.BytesIO()
# save in file-like object
plt.savefig(buffer_img, format='png')
# move to the beginning of buffer before reading (after writing)
buffer_img.seek(0)
# read from file-like object
img_bytes = buffer_img.read()
# create base64
img_encoded = "data:image/png;base64," + base64.b64encode(img_bytes).decode()
return img_encoded
if __name__ == '__main__':
app.run_server(debug=False)
所以我有这个 dash 应用程序,我想在其中根据用户的输入显示 png 图像。它有效,但问题是每次用户进行选择时,图像都会显示在前一张图像的顶部。我想以某种方式清除之前的图像,以便它只显示最近选择的图像。
在app.layout
我有:
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=[]),
])
对于回调我有:
@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())
函数 html_image
是我定义的,因为显然这是在 dash 中插入静态 png 图像的方法。
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%'})
这似乎是一种做事的方式,如果有更好的方法请告诉我,但这是唯一对我有用的方法。所以在寻找如何清除以前的输出时,我认为这很简单,但我并没有找到太多。有些帖子显示如何通过单击清除图,例如 here 但这不是我想要的,我只希望清除之前的图像,这样它们就不会重叠。如何清除我的组件以使其正确显示?
编辑:这是使用 html.Img
和 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()
要更新现有图像,您应该在 app.layout
中使用 html.Img(...)
而不是 html.Div(..., children=[])
,并更新 component_property='src'
而不是 component_property='children'
许多工具可以将 image/file 保存在使用 io.BytesIO()
file-like
对象中
matplotlib
# plot something
plt.plot(...)
# create file-like object in memory
buffer_img = io.BytesIO()
# save in file-like object
plt.savefig(buffer_img, format='png')
# move to the beginning of buffer before reading (after writing)
buffer_img.seek(0)
# read from file-like object
img_bytes = buffer_img.read()
# create base64
img_encoded = "data:image/png;base64," + base64.b64encode(img_bytes).decode()
最少的工作代码
import dash
import dash_core_components as dcc
import dash_html_components as html
import base64
import io
import matplotlib.pyplot as plt
app = dash.Dash()
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(
dash.dependencies.Output(component_id='spider_img', component_property='src'),
dash.dependencies.Input(component_id='select_group', component_property='value')
)
def update_graph(group):
# plot
plt.clf()
plt.text(5, 5, group, size=20)
plt.xlim(0, 15)
plt.ylim(0, 10)
# create file-like object in memory
buffer_img = io.BytesIO()
# save in file-like object
plt.savefig(buffer_img, format='png')
# move to the beginning of buffer before reading (after writing)
buffer_img.seek(0)
# read from file-like object
img_bytes = buffer_img.read()
# create base64
img_encoded = "data:image/png;base64," + base64.b64encode(img_bytes).decode()
return img_encoded
if __name__ == '__main__':
app.run_server(debug=False)