如何为子图列中的所有轴设置共用标题?
如何为子图列中的所有轴设置共用标题?
我明白你的需求啦——现在每个小子图都重复显示了id标题,你想让每个列(比如id1列、id2列)只在最顶部显示一次对应的标题,对吧?咱们可以调整代码的布局逻辑来实现这个效果,下面给你两种可行的方案:
方案一:基于网格布局直接添加列标题
这种方式更简洁,直接利用matplotlib的网格布局,计算每列的中心位置后添加标题:
import matplotlib.pyplot as plt categories = ["category1", "category2", "category3"] ids = ["id1", "id2"] data = [ [{"A": 1, "B": 2, "C": 3}, {"D": 4, "E": 5, "F": 6}], [{"G": 7, "H": 8, "I": 9}, {"J": 10, "K": 11, "L": 12}], [{"M": 13, "N": 14, "O": 15}, {"P": 16, "Q": 17, "R": 18}], ] # 创建整个figure并设置尺寸 fig = plt.figure(figsize=(15, 6)) # 直接创建统一的网格子图:行数量=分类数,列数量=id数 axs = fig.subplots(len(categories), len(ids), sharex=True) # 遍历子图绘制数据,同时设置行的分类标题(只给每行第一个子图设y轴标签) for row_idx, category in enumerate(categories): for col_idx, id in enumerate(ids): ax = axs[row_idx, col_idx] data_dict = data[row_idx][col_idx] ax.bar(data_dict.keys(), data_dict.values()) if col_idx == 0: ax.set_ylabel(category, fontsize=10) # 为每一列添加顶部共用标题 for col_idx, id in enumerate(ids): # 获取当前列所有子图的位置,计算列的中心x坐标 col_axes = axs[:, col_idx] left_edge = min(ax.get_position().x0 for ax in col_axes) right_edge = max(ax.get_position().x1 for ax in col_axes) center_x = (left_edge + right_edge) / 2 # 在figure顶部添加标题,y坐标设为1.02避免和图表重叠 fig.text(center_x, 1.02, id, ha='center', fontsize=12, fontweight='bold') # 调整布局,留出顶部标题的空间 plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show()
方案二:用子图分区专门放置列标题
这种方式结构更清晰,把figure分成上下两部分,顶部区域专门放列标题,底部区域放实际图表:
import matplotlib.pyplot as plt categories = ["category1", "category2", "category3"] ids = ["id1", "id2"] data = [ [{"A": 1, "B": 2, "C": 3}, {"D": 4, "E": 5, "F": 6}], [{"G": 7, "H": 8, "I": 9}, {"J": 10, "K": 11, "L": 12}], [{"M": 13, "N": 14, "O": 15}, {"P": 16, "Q": 17, "R": 18}], ] fig = plt.figure(figsize=(15, 6)) # 把figure分成上下两个子区域:顶部放标题,底部放图表,高度比例按需调整 top_subfig, bottom_subfig = fig.subfigures(2, 1, height_ratios=[0.05, 0.95]) # 顶部子区域创建对应列的占位轴,用来显示id标题 top_axs = top_subfig.subplots(1, len(ids)) for ax, id in zip(top_axs.flat, ids): ax.text(0.5, 0.5, id, ha='center', va='center', fontsize=12, fontweight='bold') ax.axis('off') # 隐藏坐标轴,只保留标题文本 # 底部子区域创建网格子图,绘制数据 bottom_axs = bottom_subfig.subplots(len(categories), len(ids)) for row_idx, category in enumerate(categories): for col_idx, id in enumerate(ids): ax = bottom_axs[row_idx, col_idx] data_dict = data[row_idx][col_idx] ax.bar(data_dict.keys(), data_dict.values()) if col_idx == 0: ax.set_ylabel(category, fontsize=10) plt.tight_layout() plt.show()
两种方案都能实现你要的效果:每列的id标题只在最顶部显示一次,而不是每个子图重复显示。你可以根据自己的代码习惯选择其中一种~
备注:内容来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

