如何为matplotlib多轴图添加坐标轴选择菜单并适配mplcursors点选功能
多寄生坐标轴场景下绑定指定激活轴的mplcursors实现方案
实现思路
- 提前存储所有已创建的寄生坐标轴、对应绘图线的映射关系,用于后续匹配校验
- 引入matplotlib内置的
Dropdown组件生成坐标轴选择菜单,用于切换当前激活的目标坐标轴 - 改写mplcursors的选中回调逻辑,仅当选中的数据点所属坐标轴与当前激活轴一致时才展示标注,否则直接丢弃本次选中事件
完整修改代码
# 新增导入Dropdown组件 from matplotlib.widgets import Dropdown import mplcursors # 其他原有导入保持不变 first = 1 offset = 60 # 新增变量:存储所有有效寄生轴和名称的映射 axis_map = {} # 新增变量:存储所有绘图线对象,用于绑定mplcursors all_lines = [] # 新增变量:存储当前激活的坐标轴 current_active_axis = None for x in range(len(cat_list)): if "Time" not in cat_list[x]: if first and not cat_list[x].startswith("EngineSpeed"): parasites[x] = ParasiteAxes(host, sharex = host) host.parasites.append(parasites[x]) parasites[x].axis["right"].set_visible(True) parasites[x].set_ylabel(cat_list[x]) parasites[x].axis["right"].major_ticklabels.set_visible(True) parasites[x].axis["right"].label.set_visible(True) p_plot, = parasites[x].plot(t, t_num_list[x], label = cat_list[x]) parasites[x].axis["right"].label.set_color(p_plot.get_color()) first = 0 # 新增:存储当前轴和线 axis_map[cat_list[x]] = parasites[x] all_lines.append(p_plot) elif not cat_list[x].startswith("EngineSpeed"): parasites[x] = ParasiteAxes(host, sharex = host) host.parasites.append(parasites[x]) parasites[x].set_ylabel(cat_list[x]) new_axisline = parasites[x].get_grid_helper().new_fixed_axis parasites[x].axis["right"+str(x+1)] = new_axisline(loc = "right", axes = parasites[x], offset = (offset, 0)) p_plot, = parasites[x].plot(t, t_num_list[x]) parasites[x].axis["right"+str(x+1)].label.set_color(p_plot.get_color()) offset = offset + 60 host.legend() # 新增:存储当前轴和线 axis_map[cat_list[x]] = parasites[x] all_lines.append(p_plot) fig.add_axes(host) # 新增:创建下拉选择菜单 # 位置参数[左, 下, 宽, 高],可根据图表布局自行调整避免重叠 ax_dropdown = fig.add_axes([0.2, 0.95, 0.6, 0.03]) dropdown_options = list(axis_map.keys()) dropdown = Dropdown(ax=ax_dropdown, label='选择激活轴: ', options=dropdown_options) # 新增:下拉菜单切换回调 def switch_active_axis(label): global current_active_axis current_active_axis = axis_map[label] dropdown.on_changed(switch_active_axis) # 初始化默认选中第一个轴 current_active_axis = axis_map[dropdown_options[0]] dropdown.set_val(dropdown_options[0]) # 新增:改造后的mplcursors选中逻辑 cursor = mplcursors.cursor(all_lines, multiple=True) @cursor.connect("add") def on_select_point(sel): # 校验选中点所属坐标轴是否为当前激活轴 if sel.artist.axes != current_active_axis: # 非激活轴的点直接取消选中,不展示标注 sel.annotation.set_visible(False) sel.remove() return # 激活轴的点正常展示标注,禁止拖拽 sel.annotation.draggable(False) # 可选:自定义标注内容,按需开启 # sel.annotation.set_text(f'X值: {sel.target[0]:.2f}\nY值: {sel.target[1]:.2f}') plt.show()
注意事项
- 下拉菜单的位置参数可根据你的实际图表布局调整,避免遮挡主图表内容
- 如需自定义标注的样式、内容,可在
on_select_point回调中修改sel.annotation的相关属性 - 若matplotlib版本较低,Dropdown组件的初始化参数可能存在差异,可对应调整适配
内容的提问来源于stack exchange,提问作者Ziga99
相关产品推荐
相关产品推荐

