清除Dash中回调时的组件

2024-04-19 10:36:51 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我有一个dash应用程序,我想根据用户的输入显示一个png图像。它可以工作,但问题是每次用户进行选择时,图像都会显示在前一个图像的顶部。我想以某种方式清除前一幅图像,使其仅显示最近选定的图像

在{}我有:

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.Imgcomponent_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()

Tags: key图像idimgpngvaluehtmlgroup
1条回答
网友
1楼 · 发布于 2024-04-19 10:36:51

要更新现有映像,您应该在app.layout中使用html.Img(...)而不是html.Div(..., children=[]),并更新component_property='src'而不是component_property='children'


许多工具都可以将图像/文件保存在使用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)

相关问题 更多 >