如何为Pandas堆叠面积图的各层级添加对应数值标注?
在Pandas堆叠面积图上标注具体数值
我来帮你搞定这个需求!要在每个构建版本和状态对应的区域标注具体数值,核心是要计算每个堆叠层的位置,然后用Matplotlib的text方法把数值精准放进去。下面是完整的可运行方案:
首先,先把你提供的DataFrame构造出来(方便复现和测试):
import pandas as pd import matplotlib.pyplot as plt # 构造你的原始数据 data = [ [120, 16.0, 120.0, 99.0, 58.0], [96, 200.0, 96.0, 117.0, 158.0], [0, 0.0, 0.0, 0.0, 0.0], [166, 108.0, 117.0, 96.0, 74.0], [126, 38.0, 25.0, 31.0, 29.0], [103, 249.0, 268.0, 283.0, 307.0], [286, 124.0, 237.0, 195.0, 132.0], [222, 238.0, 121.0, 148.0, 187.0], [103, 249.0, 268.0, 283.0, 307.0] ] # 创建多层索引 index = pd.MultiIndex.from_tuples( [ ('CTS', 'Pass'), ('CTS', 'Failed'), ('CTS', 'Didnt run'), ('SDK', 'Pass'), ('SDK', 'Failed'), ('SDK', 'Didnt run'), ('Total', 'Pass'), ('Total', 'Failed'), ('Total', 'Didnt run') ], names=['Type', 'Status'] ) # 设置列名(构建版本) columns = ['0006.39', '0006.44', '0006.50', '0007.61', '0008.66'] sum_dt = pd.DataFrame(data, index=index, columns=columns) sum_types = ['CTS', 'SDK', 'Total']
接下来,修改你的create_graphs函数,添加数值标注的逻辑:
def create_graphs(sum_dt): for t in sum_types: # 获取当前类型的数据并转置,让构建版本作为x轴 df = sum_dt.loc[t].T # 生成堆叠面积图,获取坐标轴对象 ax = df.plot(kind="area", stacked=True, title=t, color=['green', 'red', 'grey'], grid=True) # 获取每个构建版本对应的x轴坐标(分类轴对应0、1、2...的位置) x_coords = list(range(len(df.index))) # 维护一个变量记录当前堆叠层的底部高度,初始为0 bottom = pd.Series([0]*len(df.index), index=df.index) # 遍历每个状态和对应的颜色 for status, color in zip(df.columns, ['green', 'red', 'grey']): values = df[status] # 计算标注的y坐标:底部高度 + 当前层高度的一半,确保标注在区域中间 y_coords = bottom + values / 2 # 逐个添加数值标注 for x, val, y in zip(x_coords, values, y_coords): # 跳过0值的标注,避免画面混乱 if val == 0: continue # 添加文本:居中对齐,根据数值大小调整文字颜色(保证可读性) text_color = 'white' if val > 10 else 'black' ax.text(x, y, f'{val:.1f}', ha='center', va='center', fontsize=8, color=text_color) # 更新底部高度,为下一层堆叠做准备 bottom += values plt.show(block=True) # 调用函数生成带标注的图表 create_graphs(sum_dt)
关键逻辑说明:
- x坐标获取:因为x轴是构建版本的分类标签,对应的坐标是0到n-1的整数,直接用
range(len(df.index))就能拿到 - y坐标计算:堆叠面积图的每层是从上一层顶部开始累加的,所以用
bottom变量记录当前层的起始高度,标注位置取层的中间(bottom + values/2) - 标注优化:跳过0值避免冗余,根据数值大小调整文字颜色(深色背景用白色文字,浅色用黑色),保证标注清晰可读
小优化建议:
- 如果你的数值太多导致标注重叠,可以调小
fontsize或者只保留整数(把f'{val:.1f}'改成f'{int(val)}') - 可以根据自己的需求调整颜色方案,只要保证文字和背景对比明显就行
内容的提问来源于stack exchange,提问作者S.Ten
相关产品推荐
相关产品推荐

