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

Matplotlib点击直方图柱体无散点图弹出 交互需求咨询

问题原因

你遇到的现象是两个原因共同导致的:

  1. 默认状态下plt.show()是阻塞模式,代码第一次调用plt.show()弹出直方图窗口后,就会停在这个位置等待窗口关闭,后续的代码不会运行。而你在回调函数里调用plt.scatter时,默认会把散点图画到当前激活的已有画布(也就是直方图的画布)上,不会自动开新窗口。
  2. 你原来的散点图画布没有显式声明,就算画出来也会叠加在原有直方图上,再加上回调里的plt.show()和主窗口的事件循环冲突,所以看不到新窗口弹出。

解决方法

只需要修改onpick回调函数的逻辑,显式创建新的画布窗口,同时将plt.show()设置为非阻塞模式即可,顺便把你写死取class1数据的问题也修正了:

def onpick(event):
    bar = event.artist
    left = bar.get_x()
    right = left + bar.get_width()
    col_df = df[(df.nums >= left) & (df.nums <= right)].iloc[0]
    points = dict2[col_df[0]]
    # 1. 显式创建新的画布窗口,避免和原有直方图共用画布
    fig_scatter, ax_scatter = plt.subplots()
    # 2. 用当前选中类别的数据画散点,不要写死class1
    xs = [p[0] for p in points]
    ys = [p[1] for p in points]
    ax_scatter.scatter(xs, ys)
    ax_scatter.set_title(f"{col_df['classes']} 散点图")
    # 3. 非阻塞模式显示新窗口,不会和主窗口的事件循环冲突
    plt.show(block=False)

额外说明

  • 同一段代码是可以多次调用plt.show()的,只要区分阻塞/非阻塞模式即可。如果需要每次调用都新开窗口,只要每次画图前调用plt.figure()或者plt.subplots()显式创建新画布即可。
  • 你当前的代码里classes包含class7,但dict2没有对应class7的数据,点击到对应柱体时会报错,提前补全对应数据即可。
  • 后续你改成分组柱状图时,不需要用坐标匹配的方式找对应类别,可以直接给每个柱体绑定自定义的属性存类别名,匹配效率更高也不会出错。

内容的提问来源于stack exchange,提问作者Slowat_Kela

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:45:03