Matplotlib双X轴对齐并保留次轴降序排列的代码修改需求
Matplotlib双X轴对齐并保留次轴降序排列的代码修改需求
你好!我看了你提供的代码和需求——想要让双X轴对齐,同时保留次轴的降序排列,这是Matplotlib双轴图表里很常见的需求,我来帮你修改代码解决这个问题。
首先贴出你的原始代码(已经补全了缺失的导入语句):
import matplotlib.pyplot as plt import itertools # 原始代码漏了这个导入,必须加上 size = 18 value = [20, 25, 30, 35] x_values1 = list(range(0, 100, 5)) x_values2 = [0.0, 20.0, 40.0, 60.0, 80.0, 90.0, 95.0] x_values3 = [80,76,72,68,64,60,56,52,48,44,40,36,32,28,24,20,16,12,8,4] y_value1 = [8.226502331074E-07, 2.23276092438077E-06, 4.05102969501409E-06, 6.37286188209644E-06, 9.0948649799175E-06, 1.1823432395575E-05, 1.39950605433403E-05, 1.52880124352018E-05, 1.59623881451955E-05, 1.66013609598997E-05, 1.75776082796254E-05, 1.89088470296623E-05, 2.04282721607529E-05, 2.19342009434028E-05, 2.32357328236355E-05, 2.41468143248193E-05, 2.44765091608964E-05, 2.40357022548111E-05, 2.26629075512208E-05, 2.02551778821116E-05] y_value2 = [5.20787001629681E-07, 9.49836092316734E-06, 1.55921680069521E-05, 2.14212986542911E-05, 2.44079518003369E-05, 2.50048219351487E-05, 2.07892738820319E-05] fig = plt.figure(figsize=(10, 10)) #dpi=300) ax1 = fig.add_subplot(111) ax2 = ax1.twiny() prop = ax1._get_lines.prop_cycler prop = ax2._get_lines.prop_cycler marker1 = itertools.cycle(('o', '*', 'D', 'x', 's', '^', 'v', '<', '>', ',')) marker2 = itertools.cycle(('o', '*', 'D', 'x', 's', '^', 'v', '<', '>', ',')) for i in value: color = next(prop)['color'] column = 'Au_%0.3f' %(i/100) column1 = 'residual_Ag_%0.3f' %(i/100) ax1.plot(x_values1, y_value1, linewidth=3, color=color) ax1.scatter(x_values2, y_value2, marker=next(marker1), s=150, color=color) ax1.plot([], [], marker=next(marker2), label='x=%0.3f' %(i/100), linewidth=3, markersize=15, color=color) ax2.plot(x_values3, y_value1, linewidth=3, color=color) ax1.tick_params(axis='both', which='major', labelsize=25, length=10, width=2) ax2.tick_params(axis='both', which='major', labelsize=25, length=10, width=2) ax1.legend(loc='lower right', fontsize=25) ax1.set_xlabel('xlabel1', fontsize=25) ax1.set_ylabel('ylabel', fontsize=25) ax2.set_xlabel('xlabel1', fontsize=25) plt.rcParams["font.family"] = "Arial" for axis in ['top', 'bottom', 'right', 'left']: ax1.spines[axis].set_linewidth(2) ax2.spines[axis].set_linewidth(2) ax1.yaxis.get_offset_text().set_fontsize(25) plt.tight_layout() plt.show()
问题分析
默认用twiny()创建的次轴,刻度是独立于主轴的,所以会出现错位的情况。我们需要手动把次轴的刻度位置和主轴绑定,同时保留你需要的降序标签。
修改后的代码
下面是调整后的完整代码,关键修改点我会在后面说明:
import matplotlib.pyplot as plt import itertools size = 18 value = [20, 25, 30, 35] x_values1 = list(range(0, 100, 5)) x_values2 = [0.0, 20.0, 40.0, 60.0, 80.0, 90.0, 95.0] x_values3 = [80,76,72,68,64,60,56,52,48,44,40,36,32,28,24,20,16,12,8,4] y_value1 = [8.226502331074E-07, 2.23276092438077E-06, 4.05102969501409E-06, 6.37286188209644E-06, 9.0948649799175E-06, 1.1823432395575E-05, 1.39950605433403E-05, 1.52880124352018E-05, 1.59623881451955E-05, 1.66013609598997E-05, 1.75776082796254E-05, 1.89088470296623E-05, 2.04282721607529E-05, 2.19342009434028E-05, 2.32357328236355E-05, 2.41468143248193E-05, 2.44765091608964E-05, 2.40357022548111E-05, 2.26629075512208E-05, 2.02551778821116E-05] y_value2 = [5.20787001629681E-07, 9.49836092316734E-06, 1.55921680069521E-05, 2.14212986542911E-05, 2.44079518003369E-05, 2.50048219351487E-05, 2.07892738820319E-05] fig = plt.figure(figsize=(10, 10)) #dpi=300) ax1 = fig.add_subplot(111) ax2 = ax1.twiny() prop = ax1._get_lines.prop_cycler marker1 = itertools.cycle(('o', '*', 'D', 'x', 's', '^', 'v', '<', '>', ',')) marker2 = itertools.cycle(('o', '*', 'D', 'x', 's', '^', 'v', '<', '>', ',')) # 先绘制主轴内容 for i in value: color = next(prop)['color'] ax1.plot(x_values1, y_value1, linewidth=3, color=color) ax1.scatter(x_values2, y_value2, marker=next(marker1), s=150, color=color) ax1.plot([], [], marker=next(marker2), label='x=%0.3f' %(i/100), linewidth=3, markersize=15, color=color) # 关键:对齐双X轴并保留次轴降序 # 让次轴的刻度位置和主轴完全一致 ax2.set_xticks(ax1.get_xticks()) # 设置次轴的刻度标签为你需要的降序列表 ax2.set_xticklabels(x_values3) # 确保次轴的范围和主轴匹配,避免错位 ax2.set_xlim(ax1.get_xlim()) # 再绘制次轴的曲线(注意这里用主轴的x值,因为刻度已经绑定了) prop = ax1._get_lines.prop_cycler # 重新获取颜色循环,避免颜色重复 for i in value: color = next(prop)['color'] ax2.plot(x_values1, y_value1, linewidth=3, color=color) # 后续样式设置保持不变 ax1.tick_params(axis='both', which='major', labelsize=25, length=10, width=2) ax2.tick_params(axis='both', which='major', labelsize=25, length=10, width=2) ax1.legend(loc='lower right', fontsize=25) ax1.set_xlabel('xlabel1', fontsize=25) ax1.set_ylabel('ylabel', fontsize=25) ax2.set_xlabel('xlabel2', fontsize=25) # 建议修改标签名区分主次轴 plt.rcParams["font.family"] = "Arial" for axis in ['top', 'bottom', 'right', 'left']: ax1.spines[axis].set_linewidth(2) ax2.spines[axis].set_linewidth(2) ax1.yaxis.get_offset_text().set_fontsize(25) plt.tight_layout() plt.show()
核心修改点说明
- 补全
itertools导入:原始代码里用到了itertools.cycle但没导入,这会导致运行报错,必须补上。 - 分离主次轴绘制逻辑:先绘制主轴内容,再处理轴对齐,最后绘制次轴曲线,逻辑更清晰。
- 绑定刻度位置与标签:
ax2.set_xticks(ax1.get_xticks()):让次轴的每个刻度位置和主轴完全重合ax2.set_xticklabels(x_values3):把次轴的刻度标签替换成你需要的降序数值列表ax2.set_xlim(ax1.get_xlim()):强制次轴的范围和主轴一致,彻底避免错位
- 调整次轴曲线的x值:因为刻度已经和主轴绑定,所以次轴曲线要用
x_values1作为x参数,这样曲线才会和主轴的刻度对应上。 - 优化标签名:把次轴的xlabel改成
xlabel2,方便区分主次轴,你可以根据实际需求修改。
这样修改后,两个X轴的刻度会完全对齐,同时次轴保持了你需要的降序数值显示,曲线也能正确对应刻度位置。
备注:内容来源于stack exchange,提问作者Prajwal Kumar A
相关产品推荐
相关产品推荐

