如何用Gridspec创建特定布局的3×3子图:等高线与堆叠折线图
3×3子图布局实现方案
需求对应实现代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec # 生成等高线数据 x_contour = np.linspace(-5, 5, 100) y_contour = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x_contour, y_contour) Z1 = np.exp(-(X ** 2 + Y ** 2) / 10) Z2 = np.exp(-((X - 1) ** 2 + (Y - 1) ** 2) / 10) Z3 = Z1 + Z2 # 创建整体布局:3行,前两列是普通子图,第三列每行拆分为2个子图 fig = plt.figure(figsize=(12, 9)) gs = GridSpec(3, 3, figure=fig) # 第一列等高线图 ax1_1 = fig.add_subplot(gs[0, 0]) ax2_1 = fig.add_subplot(gs[1, 0]) ax3_1 = fig.add_subplot(gs[2, 0]) # 第二列等高线图 ax1_2 = fig.add_subplot(gs[0, 1]) ax2_2 = fig.add_subplot(gs[1, 1]) ax3_2 = fig.add_subplot(gs[2, 1]) # 第三列每行的两个堆叠折线图 ax1_3_top = fig.add_subplot(gs[0, 2]) ax1_3_bottom = fig.add_subplot(gs[0, 2], sharex=ax1_3_top) ax2_3_top = fig.add_subplot(gs[1, 2]) ax2_3_bottom = fig.add_subplot(gs[1, 2], sharex=ax2_3_top) ax3_3_top = fig.add_subplot(gs[2, 2]) ax3_3_bottom = fig.add_subplot(gs[2, 2], sharex=ax3_3_top) # ---------------------- 绘制等高线并统一刻度 ---------------------- # 提取统一的等高线层级,确保所有等高线图刻度一致 contour_levels = np.linspace(0, 1.2, 15) # 第一列 c1 = ax1_1.contourf(X, Y, Z1, levels=contour_levels) ax2_1.contourf(X, Y, Z2, levels=contour_levels) ax3_1.contourf(X, Y, Z3, levels=contour_levels) # 第二列 ax1_2.contourf(X, Y, Z1, levels=contour_levels) ax2_2.contourf(X, Y, Z2, levels=contour_levels) ax3_2.contourf(X, Y, Z3, levels=contour_levels) # 统一等高线图的坐标轴范围 for ax in [ax1_1, ax2_1, ax3_1, ax1_2, ax2_2, ax3_2]: ax.set_xlim(-5, 5) ax.set_ylim(-5, 5) # 添加共享的颜色条 fig.colorbar(c1, ax=[ax1_1, ax2_1, ax3_1, ax1_2, ax2_2, ax3_2], shrink=0.8) # ---------------------- 绘制折线图并统一刻度 ---------------------- # 生成折线数据 x_line = np.linspace(0, 2 * np.pi, 100) y_data = [np.sin(x_line), np.cos(x_line), np.tan(x_line), np.exp(-x_line), np.sqrt(x_line), x_line**2] # 定义折线图统一的坐标轴范围 x_line_lim = (0, 2 * np.pi) y_line_lims = [(-1.2, 1.2), (-1.2, 1.2), (-10, 10), (0, 1.2), (0, 2.5), (0, 40)] # 绘制第三列每行的两个折线图 # 第一行 ax1_3_top.plot(x_line, y_data[0]) ax1_3_bottom.plot(x_line, y_data[3]) # 第二行 ax2_3_top.plot(x_line, y_data[1]) ax2_3_bottom.plot(x_line, y_data[4]) # 第三行 ax3_3_top.plot(x_line, y_data[2]) ax3_3_bottom.plot(x_line, y_data[5]) # 统一折线图的刻度 for idx, (ax_top, ax_bottom) in enumerate([(ax1_3_top, ax1_3_bottom), (ax2_3_top, ax2_3_bottom), (ax3_3_top, ax3_3_bottom)]): ax_top.set_ylim(y_line_lims[idx]) ax_bottom.set_ylim(y_line_lims[idx+3]) ax_top.set_xlim(x_line_lim) # 隐藏上子图的x轴刻度,避免重叠 ax_top.tick_params(axis='x', labelbottom=False) # ---------------------- 设置标题与布局调整 ---------------------- ax1_1.set_title('等高线图1') ax1_2.set_title('等高线图2') ax1_3_top.set_title('折线图组1') ax2_3_top.set_title('折线图组2') ax3_3_top.set_title('折线图组3') # 调整子图间距 plt.subplots_adjust(hspace=0.4, wspace=0.3) plt.show()
关键实现说明
- 第三列堆叠布局:使用
GridSpec定义3×3全局网格,第三列的每个单元格内嵌套两个子图,通过sharex共享x轴,避免重复刻度干扰视觉。 - 等高线统一刻度:提前定义全局等高线层级
contour_levels,所有等高线图复用该层级,并添加共享颜色条,确保所有等高线图的数值刻度完全一致。 - 折线图统一刻度:为每组折线图设置统一的x/y轴范围,同时隐藏上子图的x轴标签,避免上下子图刻度重叠,保证布局整洁。
内容的提问来源于stack exchange,提问作者Rocc
相关产品推荐
相关产品推荐

