Dash回调中如何清除组件旧内容 解决PNG图片重叠显示问题
问题根源
你最初的实现是向spider_img容器的children属性返回新的html.Img节点,正常情况下Dash会直接覆盖整个children内容,不会出现图片叠加。如果出现叠加,大概率是两个原因:
- 绘图函数生成新图片时没有正确覆盖固定路径的旧文件
/tmp/spider3.png - 浏览器缓存了旧的图片内容,或者回调异常多次触发导致重复插入节点
最优解决方案
你补充的「直接更新html.Img组件的src属性」的方案本身就是更规范的实现,全程只有一个图片DOM节点,仅替换图片源,天生不会出现多图叠加的问题。如果改完后还是有异常,做两个小调整即可:
方案1:用唯一临时文件避免旧文件残留
不要用固定的临时文件名,每次生成图片用随机唯一的临时文件,用完自动删除,避免旧文件没有被覆盖的问题:
import tempfile import os import base64 @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') # 生成唯一临时png文件 with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp_file: tmp_path = tmp_file.name pyrankability.plot.spider2(A,B,file=tmp_path) # 读取图片后删除临时文件 with open(tmp_path,'rb') as f: img_bytes = f.read() os.unlink(tmp_path) return "data:image/png;base64," + base64.b64encode(img_bytes).decode()
方案2:直接内存生成图片,完全避免本地文件操作
如果你的绘图函数支持将图片写入内存流,可以直接不用写本地磁盘,性能更高,也完全没有文件残留问题:
import base64 from io import BytesIO @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') # 直接在内存中生成图片 img_buffer = BytesIO() pyrankability.plot.spider2(A,B,file=img_buffer) img_buffer.seek(0) return "data:image/png;base64," + base64.b64encode(img_buffer.read()).decode()
内容的提问来源于stack exchange,提问作者dumbitdownjr
相关产品推荐
相关产品推荐

