如何在Plotly Express分面散点图中按阈值或类别最大值添加标注?
分面散点图条件标注实现方案
需求说明
现有包含Name、Category、Value列的数据集,已使用Plotly Express绘制基于Category的分面散点图,需实现:仅为每个类别中超过特定阈值,或是该类别最大值的数值点添加文本标注。
实现步骤与代码
1. 数据预处理:标记符合条件的点
首先为每个类别计算最大值,并筛选出满足「超过阈值」或「是类别最大值」的点:
import pandas as pd import plotly.express as px # 加载数据集(示例数据,实际可替换为pd.read_csv) data = {'Name': {0: 'Alex', 1: 'Smith', 2: 'Federico', 3: 'George', 4: 'Ram', 5: 'Helen', 6: 'Mike', 7: 'Mark', 8: 'Alex', 9: 'Smith', 10: 'Federico', 11: 'George', 12: 'Ram', 13: 'Helen', 14: 'Mike', 15: 'Mark', 16: 'Alex', 17: 'Smith', 18: 'Federico', 19: 'George', 20: 'Ram', 21: 'Helen', 22: 'Mike', 23: 'Mark', 24: 'Alex', 25: 'Smith', 26: 'Federico', 27: 'George', 28: 'Ram', 29: 'Helen', 30: 'Mike', 31: 'Mark', 32: 'Alex', 33: 'Smith', 34: 'Federico', 35: 'George', 36: 'Ram', 37: 'Helen'}, 'Category': {0: 'A', 1: 'A', 2: 'A', 3: 'A', 4: 'A', 5: 'A', 6: 'A', 7: 'A', 8: 'B', 9: 'B', 10: 'B', 11: 'B', 12: 'B', 13: 'B', 14: 'B', 15: 'B', 16: 'C', 17: 'C', 18: 'C', 19: 'C', 20: 'C', 21: 'C', 22: 'C', 23: 'C', 24: 'D', 25: 'D', 26: 'D', 27: 'D', 28: 'D', 29: 'D', 30: 'D', 31: 'D', 32: 'E', 33: 'E', 34: 'E', 35: 'E', 36: 'E', 37: 'E'}, 'Value': {0: 125, 1: 399, 2: 129, 3: 147, 4: 59, 5: 169, 6: 94, 7: 142, 8: 133, 9: 54, 10: 86, 11: 49, 12: 49, 13: 64, 14: 88, 15: 65, 16: 35, 17: 89, 18: 72, 19: 62, 20: 59, 21: 198, 22: 59, 23: 109, 24: 147, 25: 108, 26: 164, 27: 110, 28: 70, 29: 321, 30: 256, 31: 58, 32: 178, 33: 121, 34: 65, 35: 251, 36: 204, 37: 303}} df = pd.DataFrame(data) # 定义阈值(可根据需求调整) THRESHOLD = 150 # 计算每个类别的最大值并添加到数据集 df['category_max'] = df.groupby('Category')['Value'].transform('max') # 标记符合条件的点:超过阈值 或 是类别最大值 df['annotate'] = (df['Value'] > THRESHOLD) | (df['Value'] == df['category_max'])
2. 绘制分面散点图
绘制包含所有类别的分面散点图,无需单独筛选某一类别:
# 绘制全部分面散点图,facet_col_wrap控制每行子图数量 fig = px.scatter(df, x="Name", y="Value", facet_col="Category", facet_col_wrap=2) # 布局样式调整 fig.update_layout( font_family="Rockwell", template='plotly_dark', title='Values by Category (Annotated: >150 or Category Max)' ) fig.update_xaxes(showticklabels=True, visible=True, showgrid=False)
3. 为符合条件的点添加标注
遍历筛选后的点,根据所属类别匹配对应分面子图,添加文本标注:
# 获取类别排序(对应分面子图的顺序) category_order = sorted(df['Category'].unique()) # 遍历添加标注 for _, row in df[df['annotate']].iterrows(): cat_idx = category_order.index(row['Category']) + 1 fig.add_annotation( x=row['Name'], y=row['Value'], text=str(row['Value']), xref=f'x{cat_idx}', yref=f'y{cat_idx}', showarrow=True, arrowhead=1, ax=0, ay=-20, # 标注向下偏移避免遮挡点 font=dict(color="white") ) # 显示图表 fig.show()
关键说明
facet_col_wrap可调整每行子图数量,避免布局拥挤- 标注的
xref和yref需对应分面子图编号,确保标注出现在正确子图中 - 可修改
THRESHOLD变量或annotate列的条件,适配不同需求
内容的提问来源于stack exchange,提问作者Ananth
相关产品推荐
相关产品推荐

