如何在Matplotlib/Seaborn的分类刻度下方添加子分类标注
在Matplotlib/Seaborn中为分类刻度添加子分类标注
针对你需要在分类刻度下方添加子分类标注的需求,以下是两种常见场景的实现方案:
场景1:每个主分类对应单个子分类
适用于你的示例数据格式,即每个主分类仅对应一个子分类。
实现代码
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd # 构造数据 data = { "Category": ["Category 1", "Category 2", "Category 3"], "Subcategory": ["Subcategory 1", "Subcategory 2", "Subcategory 3"], "Hue": ["item_x", "item_y", "item_x"], "Value": [10, 8, 6] } df = pd.DataFrame(data) # 创建绘图对象 plt.figure(figsize=(8, 5)) ax = sns.barplot(x="Category", y="Value", hue="Hue", data=df) # 获取主分类刻度的位置 tick_positions = [tick.get_x() for tick in ax.get_xticklabels()] # 在每个主分类刻度下方添加子分类文本 for pos, subcat in zip(tick_positions, df["Subcategory"]): ax.text(pos, -1, subcat, ha='center', fontsize=10, color='gray') # 调整y轴下限,避免子分类标注被截断 ax.set_ylim(bottom=-2) # 设置图表标签与标题 ax.set_xlabel("主分类") ax.set_ylabel("数值") ax.set_title("带子分类标注的柱状图") plt.tight_layout() plt.show()
关键说明
- 用
ax.text()在指定坐标位置添加子分类文本,ha='center'确保文本与主分类刻度居中对齐 - 通过
set_ylim()调整y轴范围,预留足够空间显示子分类标注 - 可根据需求调整文本的字体大小、颜色和垂直位置(第二个参数)
场景2:单个主分类对应多个子项
如果主分类下包含多个子项(如同一主分类下有多个Hue分组),可以把子分类标注在主分类组的正下方:
实现代码
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd # 构造分组数据 data = { "Category": ["Category 1", "Category 1", "Category 2", "Category 2", "Category 3", "Category 3"], "Subcategory": ["Subcategory 1", "Subcategory 1", "Subcategory 2", "Subcategory 2", "Subcategory 3", "Subcategory 3"], "Hue": ["item_x", "item_y", "item_x", "item_y", "item_x", "item_y"], "Value": [10, 7, 8, 5, 6, 4] } df = pd.DataFrame(data) # 创建绘图对象 plt.figure(figsize=(8, 5)) ax = sns.barplot(x="Category", y="Value", hue="Hue", data=df) # 计算每个主分类组的中心位置 category_positions = [] current_cat = None pos_sum = 0 count = 0 for tick in ax.get_xticklabels(): cat = tick.get_text() if cat != current_cat: if current_cat is not None: category_positions.append(pos_sum / count) current_cat = cat pos_sum = tick.get_x() count = 1 else: pos_sum += tick.get_x() count += 1 category_positions.append(pos_sum / count) # 获取每个主分类对应的子分类(假设同一主分类的子分类一致) subcat_list = df.groupby("Category")["Subcategory"].first().tolist() # 添加子分类标注 for pos, subcat in zip(category_positions, subcat_list): ax.text(pos, -1.5, subcat, ha='center', fontsize=10, color='gray') # 调整y轴范围 ax.set_ylim(bottom=-2.5) # 设置图表标签与标题 ax.set_xlabel("主分类") ax.set_ylabel("数值") ax.set_title("分组柱状图的子分类标注") plt.tight_layout() plt.show()
关键说明
- 通过遍历刻度位置,计算每个主分类组的中心坐标,确保子分类标注在组的正下方
- 使用
groupby()提取每个主分类对应的子分类,避免重复添加
内容的提问来源于stack exchange,提问作者jd_h2003
相关产品推荐
相关产品推荐

