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

如何为Python堆叠柱状图添加连接类别边缘角落的趋势线

堆叠柱状图中连接子柱状图左右角落的趋势线实现

要实现连接堆叠柱状图中每个子柱状图左右角落的趋势线,核心是获取每个主柱子的左右边界x坐标,而非中点,再对应到子柱的上下y边界。以下是修改后的完整实现:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# 示例数据(包含零值测试)
df = pd.DataFrame({
    'Category1': [1, 2, 0, 4],
    'Category2': [2, 3, 4, 5],
    'Category3': [3, 0, 5, 6]
}, index=['Bar1', 'Bar2', 'Bar3', 'Bar4'])

ax = df.plot(kind='bar', stacked=True)

# 获取柱状图的宽度(堆叠柱的主柱子宽度统一)
bar_width = ax.patches[0].width

# 计算累积和,确定每个子柱状图的上边界y值
df_cumsum = df.cumsum(axis=1)

# 遍历每个类别,绘制对应子柱的上下边缘趋势线
for i, category in enumerate(df.columns):
    # 子柱的上、下边界y值
    y_upper = df_cumsum[category].values
    y_lower = y_upper - df[category].values
    # 主柱子的中点x坐标
    x_mid = np.arange(len(df))
    
    # 计算每个主柱子的左右边界x坐标
    x_left = x_mid - bar_width / 2
    x_right = x_mid + bar_width / 2
    
    # 构建上边缘的点序列:依次连接每个子柱的左角落→右角落
    x_upper_points = np.array([[left, right] for left, right in zip(x_left, x_right)]).flatten()
    y_upper_points = np.array([[y, y] for y in y_upper]).flatten()
    
    # 构建下边缘的点序列:依次连接每个子柱的左角落→右角落
    x_lower_points = np.array([[left, right] for left, right in zip(x_left, x_right)]).flatten()
    y_lower_points = np.array([[y, y] for y in y_lower]).flatten()
    
    # 绘制趋势线,添加标记区分
    plt.plot(x_upper_points, y_upper_points, marker='o', linestyle='-', label=f'{category} 上边缘')
    plt.plot(x_lower_points, y_lower_points, marker='s', linestyle='--', label=f'{category} 下边缘')

plt.legend(loc='upper left')
plt.tight_layout()
plt.show()

关键修改说明

  1. 获取柱状图宽度:通过ax.patches获取所有绘制的子柱子,提取第一个柱子的width属性,得到主柱子的统一宽度。
  2. 生成左右边界坐标:每个主柱子的中点为np.arange(len(df)),左右边界通过中点±宽度/2计算得到。
  3. 构建连贯点序列:将每个柱子的左右x坐标与对应的上下y值配对展平,确保折线依次连接每个子柱的左、右角落,完全贴合子柱边缘。
  4. 零值兼容:当类别数值为0时,上下边界y值相等,折线会自动变为水平线段,不会出现异常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:42:50