Plotly Python中Checkbox部件失效:取消勾选后图表线条未移除
问题分析与解决方案
你的代码核心问题是只实现了勾选复选框添加曲线的逻辑,完全没处理取消勾选时移除对应曲线的分支,同时还有几个冗余/不合理的设计:
validate1/validate2这类函数完全没必要,它们只判断勾选状态,导致取消勾选时没有任何代码执行- 初始创建
FigureWidget时添加的空scatter会在图表里留下多余的空曲线 - 多次勾选同一个复选框会重复添加相同曲线,因为没有检查该曲线是否已存在
修正后的代码(简洁版)
思路是每次复选框状态变化时,根据当前勾选状态重新构建图表的曲线列表,避免重复和残留:
import pandas as pd import plotly.graph_objects as go from ipywidgets import widgets # 读取并预处理数据 url = "https://entrepot.metropolegrenoble.fr/opendata/200040715-MET/insee/etat_civil_200040715.csv" data_pop = pd.read_csv(url) data_pop.drop(["code_postal"], axis=1, inplace=True) # 创建复选框组件 use_Gre = widgets.Checkbox(description='Grenoble', value=False) use_Viz = widgets.Checkbox(description='Vizille', value=False) container_1 = widgets.HBox(children=[use_Gre, use_Viz]) # 初始化空图表 g = go.FigureWidget() # 统一的图表更新函数 def update_chart(change): with g.batch_update(): # 清空现有所有曲线 g.data = [] # 根据勾选状态添加对应曲线 if use_Gre.value: gre_data = data_pop[data_pop['commune'] == "Grenoble"] g.add_scatter(x=gre_data['annee'], y=gre_data['nombre_naissances'], name="Grenoble") if use_Viz.value: viz_data = data_pop[data_pop['commune'] == "Vizille"] g.add_scatter(x=viz_data['annee'], y=viz_data['nombre_naissances'], name="Vizille") # 绑定复选框的状态变化事件 use_Gre.observe(update_chart, names="value") use_Viz.observe(update_chart, names="value") # 显示组件 widgets.VBox([container_1, g])
精细版(不清空所有曲线,单独添加/移除)
如果不想每次清空所有曲线,可通过曲线的name识别并单独操作:
import pandas as pd import plotly.graph_objects as go from ipywidgets import widgets # 读取并预处理数据 url = "https://entrepot.metropolegrenoble.fr/opendata/200040715-MET/insee/etat_civil_200040715.csv" data_pop = pd.read_csv(url) data_pop.drop(["code_postal"], axis=1, inplace=True) # 创建复选框组件 use_Gre = widgets.Checkbox(description='Grenoble', value=False) use_Viz = widgets.Checkbox(description='Vizille', value=False) container_1 = widgets.HBox(children=[use_Gre, use_Viz]) # 初始化空图表 g = go.FigureWidget() # 精细控制的更新函数 def update_chart(change): with g.batch_update(): # 处理Grenoble曲线 gre_exists = any(trace.name == "Grenoble" for trace in g.data) if use_Gre.value and not gre_exists: gre_data = data_pop[data_pop['commune'] == "Grenoble"] g.add_scatter(x=gre_data['annee'], y=gre_data['nombre_naissances'], name="Grenoble") elif not use_Gre.value and gre_exists: g.data = [t for t in g.data if t.name != "Grenoble"] # 处理Vizille曲线 viz_exists = any(trace.name == "Vizille" for trace in g.data) if use_Viz.value and not viz_exists: viz_data = data_pop[data_pop['commune'] == "Vizille"] g.add_scatter(x=viz_data['annee'], y=viz_data['nombre_naissances'], name="Vizille") elif not use_Viz.value and viz_exists: g.data = [t for t in g.data if t.name != "Vizille"] # 绑定事件 use_Gre.observe(update_chart, names="value") use_Viz.observe(update_chart, names="value") # 显示组件 widgets.VBox([container_1, g])
内容的提问来源于stack exchange,提问作者Elise1369
相关产品推荐
相关产品推荐

