Matplotlib自定义X轴标签后,如何显示鼠标悬停X坐标及适配mplcursors?
解决Matplotlib自定义X轴标签后坐标显示为空及mplcursors异常问题
问题说明
- 给X轴设置重复自定义标签后,鼠标悬停图表时右上角的X坐标显示为空
- 用
ax.xaxis.set_major_formatter('{x:g}')能恢复坐标显示,但会覆盖自定义标签 mplcursors出现异常:点击数据点之间的线段时X值为空,精准点击数据点仅显示标签,无法查看底层数值型X坐标(标签"A"/"B"/"C"缺少次级轴上下文毫无意义)
解决方案
核心思路是自定义一个Formatter类,同时兼顾X轴的自定义标签显示,以及坐标提示、mplcursors的原始数值输出:
- 继承
matplotlib.ticker.Formatter,实现两个关键方法:format_tick:控制X轴上显示的自定义标签format_data:控制坐标提示和mplcursors里显示的原始数值
- 替换原有的
set_xticks(labels=...)方式,改用自定义Formatter绑定到X轴 - 给mplcursors绑定事件,强制注解显示原始X数值
完整代码示例
import matplotlib.pyplot as plt import numpy as np import mplcursors from matplotlib.ticker import Formatter class CustomXFormatter(Formatter): def __init__(self, labels): self.labels = labels def format_tick(self, value, pos=None): # 轴上显示自定义标签,仅在有效索引范围内返回对应内容 idx = int(value) if 0 <= idx < len(self.labels): return self.labels[idx] return '' def format_data(self, value): # 坐标提示和mplcursors显示原始数值 return f'{value:g}' x = np.arange(0, 9) y = np.random.rand(*x.shape) labels = ['A', 'B', 'C']*3 fig, ax = plt.subplots() ax.plot(x, y, 'bx-', label='random') ax.set_xticks(x) # 仅设置刻度位置,不指定labels参数 ax.xaxis.set_major_formatter(CustomXFormatter(labels)) # 绑定自定义Formatter # 配置mplcursors,确保点击任何位置都显示原始X数值 cursor = mplcursors.cursor(multiple=True) @cursor.connect("add") def on_add(sel): # 手动构造注解文本,显示原始X和Y数值 sel.annotation.set_text(f'X: {sel.target[0]:g}\nY: {sel.target[1]:.4f}') plt.show()
效果说明
- 鼠标悬停时,右上角坐标提示正常显示X的原始数值,同时X轴保留自定义标签
- 点击数据点或线段时,mplcursors的注解都会显示原始X数值,不再出现空值或仅显示标签的情况
内容的提问来源于stack exchange,提问作者DrAl
相关产品推荐
相关产品推荐

