如何在Seaborn FacetGrid分组柱状图中添加flag列自定义标注
为Seaborn FacetGrid柱状图添加Flag标记
实现思路
Seaborn的FacetGrid会按指定的row和col参数拆分数据生成子图,我们可以通过遍历每个子图对应的分组键,筛选原始DataFrame中对应的数据,再给每个柱子匹配flag列的内容并添加文本。
完整代码
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd df = pd.DataFrame([ ['C', 'G1', 'gbt', 'auc', 0.7999, "†"], ['C', 'G1', 'gbtv2', 'auc', 0.8199, "*"], ['C', 'G1', 'gbt', 'pr@2%', 0.0883, "*"], ['C', 'G1', 'gbt', 'pr@10%', 0.0430, ""], ['C', 'G2', 'gbt', 'auc', 0.7554, ""], ['C', 'G2', 'gbt', 'pr@2%', 0.0842, ""], ['C', 'G2', 'gbt', 'pr@10%', 0.0572, ""], ['C', 'G3', 'gbt', 'auc', 0.7442, ""], ['C', 'G3', 'gbt', 'pr@2%', 0.0894, ""], ['C', 'G3', 'gbt', 'pr@10%', 0.0736, ""], ['E', 'G1', 'gbt', 'auc', 0.7988, ""], ['E', 'G1', 'gbt', 'pr@2%', 0.0810, ""], ['E', 'G1', 'gbt', 'pr@10%', 0.0354, ""], ['E', 'G1', 'gbtv3', 'pr@10%', 0.0454, ""], ['E', 'G2', 'gbt', 'auc', 0.7296, ""], ['E', 'G2', 'gbt', 'pr@2%', 0.1071, ""], ['E', 'G2', 'gbt', 'pr@10%', 0.0528, "†"], ['E', 'G3', 'gbt', 'auc', 0.6958, ""], ['E', 'G3', 'gbt', 'pr@2%', 0.1007, ""], ['E', 'G3', 'gbt', 'pr@10%', 0.0536, "†"], ], columns=["src", "grp", "model", "metric", "val", "flag"]) # 绘制FacetGrid柱状图 cat = sns.catplot(data=df, x="grp", y="val", hue="model", kind="bar", sharey=False, col="metric", row="src") # 遍历每个子图,添加flag文本 for row_idx, src_val in enumerate(cat.row_names): for col_idx, metric_val in enumerate(cat.col_names): # 获取当前子图的轴对象 ax = cat.facet_axis(row_idx, col_idx) # 筛选当前子图对应的数据集 subset = df[(df['src'] == src_val) & (df['metric'] == metric_val)] # 按grp和model排序,确保和柱子顺序一致 subset = subset.sort_values(['grp', 'model']) # 遍历每个柱子和对应的flag for patch, flag in zip(ax.patches, subset['flag']): if flag: # 只添加非空的flag # 计算柱子中心的x坐标,顶部的y坐标 x = patch.get_x() + patch.get_width() / 2 y = patch.get_height() # 添加文本 ax.text(x, y, flag, ha='center', va='bottom', fontsize=12) plt.show()
关键说明
- 通过
cat.row_names和cat.col_names获取所有分组的键值,遍历每个子图对应的src和metric - 筛选出当前子图对应的数据集后,必须按
grp和model排序,保证和柱子的绘制顺序一致 - 利用
patch.get_x()、patch.get_width()、patch.get_height()计算文本的位置,ha='center'确保水平居中,va='bottom'让文本在柱子顶部显示 - 只对非空的
flag值添加文本,避免空字符串干扰
内容的提问来源于stack exchange,提问作者ironv
相关产品推荐
相关产品推荐

