如何按hue分组或基于全数据集为lmplot分面添加标注
解决Seaborn lmplot中回归r/p值标注重叠问题
在用Seaborn的
lmplot绘制带hue分组的回归图时,每个分面会生成两条回归线,导致自动映射的r值、p值标注重叠。需求分为两种:要么让不同hue分组的标注位于不同位置,要么基于分面的完整数据集(而非按hue拆分的子集)计算并展示标注。
方案一:按hue分组调整标注位置
利用map_dataframe按hue分组传递数据的特性,在标注函数中根据当前分组调整文本垂直位置,避免重叠。
完整代码:
import pandas as pd import seaborn as sns import scipy as sp import matplotlib.pyplot as plt dict = { 'ID': ['A','B','C','D','A','B','C','D','A','B','C','D','A','B','C','D'], 'SCORE': [18,20,37,40,34,21,24,12,34,54,23,43,23,31,65,78], 'AGE': [34,54,46,65,43,23,54,23,43,54,23,32,56,42,12,43], 'GENDER': [1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2] } df = pd.DataFrame(dict) g = sns.lmplot(x='SCORE', y='AGE', data=df, hue='GENDER', col='ID', height=3, aspect=1) def annotate(data, **kws): r, p = sp.stats.pearsonr(data['SCORE'], data['AGE']) ax = plt.gca() # 根据hue分组调整y坐标,区分不同分组的标注位置 y_pos = 0.8 if data['GENDER'].iloc[0] == 1 else 0.7 ax.text(.05, y_pos, f'GENDER={data["GENDER"].iloc[0]}\nr={r:.2f}, p={p:.2g}', transform=ax.transAxes, bbox=dict(facecolor='white', alpha=0.7)) g.map_dataframe(annotate) plt.show()
说明
- 通过
data['GENDER'].iloc[0]识别当前分组的hue值,为不同分组设置差异化的垂直位置 - 添加半透明白色背景框,提升标注文本的可读性
- 标注中加入分组标识,方便对应到对应颜色的回归线
方案二:基于分面完整数据集计算标注
如果需要展示每个分面(按ID划分)整体数据的回归指标,可直接遍历FacetGrid的axes_dict,提取分面完整数据计算后标注。
完整代码:
import pandas as pd import seaborn as sns import scipy as sp import matplotlib.pyplot as plt dict = { 'ID': ['A','B','C','D','A','B','C','D','A','B','C','D','A','B','C','D'], 'SCORE': [18,20,37,40,34,21,24,12,34,54,23,43,23,31,65,78], 'AGE': [34,54,46,65,43,23,54,23,43,54,23,32,56,42,12,43], 'GENDER': [1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2] } df = pd.DataFrame(dict) g = sns.lmplot(x='SCORE', y='AGE', data=df, hue='GENDER', col='ID', height=3, aspect=1) # 遍历每个分面的ID与对应坐标轴 for id_val, ax in g.axes_dict.items(): # 提取当前分面的全部数据 facet_data = df[df['ID'] == id_val] r, p = sp.stats.pearsonr(facet_data['SCORE'], facet_data['AGE']) # 在固定位置标注整体数据的回归指标 ax.text(.05, .8, f'整体数据\nr={r:.2f}, p={p:.2g}', transform=ax.transAxes, bbox=dict(facecolor='white', alpha=0.7)) plt.show()
说明
g.axes_dict存储了分面名称(ID值)与对应坐标轴的映射关系,直接遍历即可定位每个分面- 基于分面完整数据计算皮尔逊相关系数,展示整体数据的回归特征
- 标注位置固定,不会与hue分组的回归线标注冲突(若不需要分组标注,可移除方案一中的
map_dataframe调用)
内容的提问来源于stack exchange,提问作者user20501139
相关产品推荐
相关产品推荐

