Matplotlib点击直方图柱体无散点图弹出 交互需求咨询
问题原因
你遇到的现象是两个原因共同导致的:
- 默认状态下
plt.show()是阻塞模式,代码第一次调用plt.show()弹出直方图窗口后,就会停在这个位置等待窗口关闭,后续的代码不会运行。而你在回调函数里调用plt.scatter时,默认会把散点图画到当前激活的已有画布(也就是直方图的画布)上,不会自动开新窗口。 - 你原来的散点图画布没有显式声明,就算画出来也会叠加在原有直方图上,再加上回调里的
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
相关产品推荐
相关产品推荐

