You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建带标注分位线段的年度数据可视化图表

问题描述

我想制作一种类似堆叠柱状图的图表(不确定准确名称),手绘了2016和2017年的示例图(未附上)。现有生成DataFrame的代码如下,但当前代码生成的是堆叠柱状图,并非我需要的效果。我需要针对每个年份,在对应位置用带标注的水平线段展示各百分位数的数值,请问如何实现?这是否属于修改版Stacked Bar Chart?

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

data = [[2016.0, 0.4862, 0.4115, 0.3905, 0.3483, 0.1196],
 [2017.0, 0.4471, 0.4096, 0.3725, 0.2866, 0.1387],
 [2018.0, 0.4748, 0.4016, 0.3381, 0.2905, 0.2012],
 [2019.0, 0.4705, 0.4247, 0.3857, 0.3333, 0.2457],
 [2020.0, 0.4755, 0.4196, 0.3971, 0.3825, 0.2965]]

cols = ['attribute_time', '100-81 percentile', '80-61 percentile', '60-41 percentile', '40-21 percentile', '20-0 percentile']
df = pd.DataFrame(data, columns=cols)
#set seaborn plotting aesthetics
sns.set(style='white')
#create stacked bar chart
df.set_index('attribute_time').plot(kind='bar', stacked=True)
解决方案

图表类型说明

这种图表不属于修改版堆叠柱状图:堆叠柱状图的核心是数值累加堆叠,用面积占比展示总和与细分项的关系;而你的需求是在每个年份的垂直位置上,独立标记多个百分位数的数值长度,更适合称为类别式多水平标记图,也可看作平行坐标图针对类别轴的简化形式。

实现代码

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 初始化数据
data = [[2016.0, 0.4862, 0.4115, 0.3905, 0.3483, 0.1196],
 [2017.0, 0.4471, 0.4096, 0.3725, 0.2866, 0.1387],
 [2018.0, 0.4748, 0.4016, 0.3381, 0.2905, 0.2012],
 [2019.0, 0.4705, 0.4247, 0.3857, 0.3333, 0.2457],
 [2020.0, 0.4755, 0.4196, 0.3971, 0.3825, 0.2965]]

cols = ['attribute_time', '100-81 percentile', '80-61 percentile', '60-41 percentile', '40-21 percentile', '20-0 percentile']
df = pd.DataFrame(data, columns=cols)

# 设置绘图风格
sns.set(style='whitegrid')
fig, ax = plt.subplots(figsize=(10, 6))

# 获取年份的垂直位置(y轴坐标)
year_positions = range(len(df['attribute_time']))
years = df['attribute_time'].astype(int)

# 遍历每个百分位数列,绘制水平线段并添加标注
for col_idx, col in enumerate(cols[1:]):
    values = df[col]
    # 绘制水平线段:y轴对应年份位置,x从0延伸到百分位数数值
    ax.hlines(y=year_positions, xmin=0, xmax=values, color=f'C{col_idx}', linewidth=3, label=col)
    # 在线段末端添加数值标注
    for y, val in zip(year_positions, values):
        ax.text(val + 0.01, y, f'{val:.4f}', va='center', fontsize=9)

# 配置轴标签与刻度
ax.set_yticks(year_positions)
ax.set_yticklabels(years)
ax.set_xlabel('Percentile Value')
ax.set_ylabel('Year')
ax.set_title('Percentile Values by Year')

# 调整图例位置避免遮挡
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

# 优化布局
plt.tight_layout()
plt.show()

代码关键说明

  • 使用ax.hlines()绘制水平线段,每个百分位数用不同颜色区分,线段长度直接对应该年份的百分位数数值
  • 通过ax.text()在每个线段末端添加数值标注,确保数据可读性
  • 将y轴设置为年份类别,每个年份对应固定垂直位置,清晰区分不同年份的数据
  • 调整图例位置到图表外侧,避免遮挡核心内容

内容的提问来源于stack exchange,提问作者BrianBeing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:40:42