You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 00:12:12