如何在Matplotlib子图的ax2轴混合显示两类数据集的xticklabels?
实现双数据集上下分栏的X轴标签
这问题我之前做可视化时也遇到过,想要在同一个副轴(ax2)上分别显示两个数据集的标签,其实可以通过为ax2设置主、次两组独立刻度,并调整标签的垂直位置来实现。先帮你分析下之前伪代码的问题,再给出完整解决方案:
你之前伪代码的问题
- 长度不匹配:
X2_orange[ind_pos_Bd3]有9个元素,而X1_green[ind_pos_Pd3]只有5个,zip后会只保留到较短的长度,丢失orange的部分标签; - 格式化语法错误:
"%.2f \n %.2f" % i里的i是元组,应该写成"%.2f \n %.2f" % (a, b); - 布局不合理:即使语法正确,换行后的标签会重叠在一起,无法实现清晰的上下分栏效果。
解决方案:主刻度+次刻度分离显示
我们可以把orange数据集的标签放在ax2轴的上方(主刻度),green数据集的标签放在ax2轴的下方(次刻度),通过调整标签的垂直对齐方式和间距来避免重叠。
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as mtick from matplotlib.ticker import FixedLocator, FixedFormatter X1_orange = np.array([ 10., 30.1, 50.2, 70.3, 90.4, 110.51, 130.61, 150.71, 170.81, 190.91, 211.01, 231.11, 251.21, 271.31, 291.41, 311.52, 331.62, 351.72, 371.82, 391.92, 412.02, 432.12, 452.22, 472.32, 492.42, 512.53, 532.63, 552.73, 572.83, 592.93, 613.03, 633.13, 653.23]) X2_orange = np.array([ 2.56691976, 2.5781089 , 2.59624855, 2.62275805, 2.64568568, 2.66607658, 2.6959714 , 2.7231501 , 2.75529391, 2.78894345, 2.81573712, 2.84711104, 2.88437499, 2.9191375 , 2.95033337, 2.99340594, 3.02206115, 3.06383265, 3.08649135, 3.12707204, 3.18500195, 3.24240915, 3.25965166, 3.36137181, 3.35468811, 3.42661704, 3.46254097, 3.61136855, 3.65505401, 3.89043407, 3.80421353, 3.79380128, 4.01570509]) X1_green = np.array([ 10. , 30.1 , 50.2 , 70.3 , 90.4 , 110.51, 130.61, 150.71, 170.81, 190.91, 211.01, 231.11, 251.21, 271.31, 291.41, 311.52, 331.62]) X2_green = np.array([ 1.9894731 , 2.00259207, 2.01875725, 2.04333825, 2.07700656, 2.09629866, 2.14727031, 2.17488234, 2.2499103 , 2.2698862 , 2.31607409, 2.41452705, 2.50847008, 2.61117044, 2.70657103, 3.25283819, 3.31585812]) Y0_orange = np.array([-1.87483583, -1.82358431, -1.78627169, -1.75242213, -1.7299256 , -1.69363695, -1.64623615, -1.59656948, -1.56967972, -1.55058869, -1.51874314, -1.45673839, -1.40554361, -1.39904184, -1.35322104, -1.33906865, -1.30865871, -1.28099683, -1.24897269, -1.19802619, -1.17268543, -1.13523614, -1.09290541, -1.05642197, -1.00189406, -0.95390527, -0.90890049, -0.82522042, -0.76334378, -0.64504498, -0.62782754, -0.47358849, -0.49772039]) Y0_green = np.array([-1.97113854, -1.92908192, -1.84404067, -1.75333855, -1.67575628, -1.58010168, -1.48746063, -1.40770641, -1.31802444, -1.2302243 , -1.14927205, -1.04251178, -0.91661452, -0.82924669, -0.65075739, -0.37715382, -0.21349827]) ##### THREE SUBPLOTS:: ###### # Y0 plot: f, axarr = plt.subplots(3, sharex=True, figsize=(11,5)) axarr[0].plot(X1_orange, Y0_orange, linestyle='--', marker="o", markersize=6, color='orange') axarr[0].plot(X1_green, Y0_green, linestyle='--', marker="o", markersize=6, color='green') axarr[0].set_ylabel('Y0', fontsize=15) # Create a new axis: axarr[0].grid() ax2 = axarr[0].twiny() # Make the ax1-ticks and ax1-tick-labels match the line color (blue): axarr[0].tick_params('x', colors='blue') # Make the ax2-ticks and ax2-tick-labels match the red color: # this only controls the font and color of label ax2.set_xlabel('x2', fontsize=14, color='red') # Set xlimits of ax2 the same as ax1 ax2.set_xlim(axarr[0].get_xlim()) # -------------------------- # 核心修改部分:上下分栏显示标签 # -------------------------- # 1. 设置orange数据集的主刻度(标签在ax2上方) ind_pos_Bd3 = [0, 4, 8, 12, 16, 20, 24, 28, 32] ax2.set_xticks(X1_orange[ind_pos_Bd3]) ax2.set_xticklabels(["%.2f" % i for i in X2_orange[ind_pos_Bd3]], verticalalignment='bottom', # 标签放在刻度线下方(即轴的上方区域) pad=15, # 增加与轴的间距,避免重叠 color='orange') ax2.tick_params(axis='x', which='major', colors='orange') # 2. 设置green数据集的次刻度(标签在ax2下方) ind_pos_Pd3 = [0, 4, 8, 12, 16] # 自定义次刻度位置 ax2.xaxis.set_minor_locator(FixedLocator(X1_green[ind_pos_Pd3])) # 自定义次刻度标签 ax2.xaxis.set_minor_formatter(FixedFormatter(["%.2f" % i for i in X2_green[ind_pos_Pd3]])) # 调整次刻度标签的样式和位置 ax2.tick_params(axis='x', which='minor', colors='green', verticalalignment='top', # 标签放在刻度线上方(即轴的下方区域) pad=15) # 增加与轴的间距 plt.tight_layout() plt.show()
代码说明
- 主刻度(orange):用
set_xticks和set_xticklabels设置,通过verticalalignment='bottom'让标签位于刻度线的下方(也就是ax2轴的上方区域),pad=15增加间距避免和下方标签重叠; - 次刻度(green):用
FixedLocator和FixedFormatter自定义次刻度的位置和标签,通过verticalalignment='top'让标签位于刻度线的上方(也就是ax2轴的下方区域),同样用pad调整间距; - 颜色区分:分别设置主/次刻度的颜色和对应数据集一致,提高可读性。
这样就能实现你想要的ax2轴上下分栏显示两个数据集标签的效果啦!
内容的提问来源于stack exchange,提问作者DavidC.
相关产品推荐
相关产品推荐

