使用ipywidgets构建GUI时点击按钮无法清除图表输出求助
问题:ipywidgets切换按钮时图表无法清除的解决办法
我正在用ipywidgets构建GUI,点击按钮能显示NBA球员信息和对应图表,但切换按钮时旧图表没法清除。试过clear_output()、plt.close()都没用,求解决建议。
示例图表数据
import numpy as np import matplotlib.pyplot as plt x = np.array([1,2,3]) y = x/4 a = np.array(['sales', 'customer', 'interaction']) b = np.array([300, 200, 1000])
原按钮点击函数
from IPython.core.interactiveshell import IPython from IPython.display import display, clear_output output = ipywidgets.widgets.Output() def on_btn_click(btn): with output: clear_output() plt.close() if btn.description == 'Avery Bradley': print (file.loc[0]), plt.plot(x,y) if btn.description == 'Jae Crowder': print (file.loc[1]), plt.bar(a,b) '''if btn.description == 'John Holland': print (file.loc[2]) if btn.description == 'R.J. Hunter': print (file.loc[3]) if btn.description == 'Jonas Jerebko': print (file.loc[4]) if btn.description == 'Amir Johnson': print (file.loc[5]) if btn.description == 'Jordan Mickey': print (file.loc[6]) if btn.description == 'Kelly Olynyk': print (file.loc[7]) if btn.description == 'Terry Rozier': print (file.loc[8]) if btn.description == 'Marcus Smart': print (file.loc[9]) if btn.description == 'Jared Sullinger': print (file.loc[10]) if btn.description == 'Isaiah Thomas': print (file.loc[11])'''
创建按钮代码
button_list = [] for i in range (0,12): button = ipywidgets.widgets.Button(description=image_name[i]['name']) button.on_click(on_btn_click) button_list.append(button)
按钮布局代码
grid = widgets.Grid(1,6, header_column=True, header_row=True) newsize = (100,100) for (row, col) in grid: index = row*6+col print("") display(image_name[index]['image'].resize(newsize)) display(button_list[index]) for (row, col) in grid: index = row*6+col print("") display(image_name[index+6]['image'].resize(newsize)) display(button_list[index+6]) display(output)
已尝试的无效方法
方法1:添加plt.close()
from IPython.core.interactiveshell import IPython from IPython.display import display, clear_output output = ipywidgets.widgets.Output() def on_btn_click(btn): with output: clear_output() plt.close() # 尝试添加此行 if btn.description == 'Avery Bradley': print (file.loc[0]), plt.plot(x,y) if btn.description == 'Jae Crowder': print (file.loc[1]), plt.bar(a,b)
方法2:调整clear_output()位置
from IPython.core.interactiveshell import IPython from IPython.display import display, clear_output output = ipywidgets.widgets.Output() def on_btn_click(btn): with output: clear_output() if btn.description == 'Avery Bradley': print (file.loc[0]), plt.plot(x,y) clear_output(), print (file.loc[1]), plt.bar(a,b) print (file.loc[1]), clear_output(), plt.bar(a,b) print (file.loc[1]), plt.bar(a,b), clear_output() if btn.description == 'Jae Crowder': clear_output(), print (file.loc[1]), plt.bar(a,b) # 尝试三种顺序 print (file.loc[1]), clear_output(), plt.bar(a,b) print (file.loc[1]), plt.bar(a,b), clear_output() # 还试过替换成plt.close()
解决办法
方案1:彻底关闭所有图表+显式渲染
修改按钮点击函数,用plt.close('all')关闭所有旧图表,同时添加wait=True避免渲染闪烁,最后显式调用plt.show():
def on_btn_click(btn): with output: clear_output(wait=True) # 先清空再渲染,避免闪烁 plt.close('all') # 关闭所有已存在的图表实例 if btn.description == 'Avery Bradley': print(file.loc[0]) plt.plot(x,y) plt.show() if btn.description == 'Jae Crowder': print(file.loc[1]) plt.bar(a,b) plt.show()
方案2:使用独立Figure对象管理图表
每次点击都创建新的Figure和Axes,彻底隔离新旧图表:
def on_btn_click(btn): with output: clear_output(wait=True) # 每次点击生成全新的图表容器 fig, ax = plt.subplots() if btn.description == 'Avery Bradley': print(file.loc[0]) ax.plot(x,y) if btn.description == 'Jae Crowder': print(file.loc[1]) ax.bar(a,b) plt.show() plt.close(fig) # 关闭当前Figure,释放资源
方案3:使用ipympl后端嵌入图表
先安装依赖:
pip install ipympl
在Notebook中启用widget化matplotlib:
%matplotlib widget
之后图表会作为ipywidgets组件渲染,清除时更彻底,配合clear_output()即可解决残留问题。
内容的提问来源于stack exchange,提问作者daza
相关产品推荐
相关产品推荐

