Matplotlib 3.8.x交互式双子图双X轴同步问题修复求助
Matplotlib 3.8.x 双(子)图双X轴同步修复方案
数年前我曾发布过《双(子)图中交互式Matplotlib的双X轴同步?》的问题并获得可行方案,但Matplotlib API更新后,原代码中ax.get_shared_x_axes().join(ax, ax2, ax22)语句出现AttributeError: 'GrouperView' object has no attribute 'join'错误;参考相关方案改用sharex()方法时,又触发ValueError: x-axis is already shared错误。以下是适配Matplotlib 3.8.x版本的修复代码及说明。
修复后的完整代码
#!/usr/bin/env python3 import matplotlib print("matplotlib.__version__ {}".format(matplotlib.__version__)) import matplotlib.pyplot as plt import matplotlib.ticker as ticker import packaging # 测试数据 x_seq = [x / 100.0 for x in range(1, 100)] y_seq = [x**2 for x in x_seq] y2_seq = [0.3*x**2 for x in x_seq] # 创建上下两个子图,共享X轴 fig, (ax, ax2) = plt.subplots(2, 1, sharex=True, figsize=(9, 6), dpi=100, gridspec_kw={'height_ratios': [2, 1]}) # 消除子图间的水平间距 fig.subplots_adjust(hspace=0) # 给ax2创建双X轴(共享Y轴) ax22 = ax2.twiny() # 根据Matplotlib版本选择X轴同步方式 if packaging.version.Version(matplotlib.__version__) < packaging.version.Version("3.7"): ax.get_shared_x_axes().join(ax, ax2, ax22) else: # Matplotlib 3.7+ 版本:将ax22加入ax和ax2的X轴共享组 ax.get_shared_x_axes().add(ax22) # 调整双X轴的位置到下方 ax22.xaxis.set_ticks_position("bottom") ax22.xaxis.set_label_position("bottom") ax22.spines["bottom"].set_position(("axes", -0.1)) # 绘制曲线 ax.plot(x_seq, y_seq) ax2.plot(x_seq, y2_seq) # 双X轴刻度转换因子 factor = 655 # 自定义刻度格式化函数 @ticker.FuncFormatter def major_formatter(x, pos): return int(factor*x) ax22.xaxis.set_major_formatter(major_formatter) # 显示图像 plt.show()
关键修改说明
Matplotlib 3.7+ API变化适配:
- 旧版本的
join方法被移除,get_shared_x_axes()返回的GrouperView对象提供add方法,可直接将新轴加入已有的共享组。 - 无需重复调用
sharex(),因为ax和ax2已经通过subplots(sharex=True)建立了共享关系,只需将ax22加入该共享组即可实现三者的X轴同步。
- 旧版本的
错误原因解析:
- 原
sharex()调用报错是因为ax与ax2的X轴共享已存在,重复调用会触发冲突。 join方法移除后,改用共享组的add方法是官方推荐的新方式,能确保三个轴的X轴交互(如缩放、平移)保持同步。
- 原
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

