如何注释具有最大高度的堆叠条的顶部 [已关闭]

How to annotated the top of a stacked bar with the greatest height [closed]

提问人:Ayman M 提问时间:11/14/2023 最后编辑:Trenton McKinneyAyman M 更新时间:11/15/2023 访问量:76

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

2天前关闭。

我有下面的图表,我想用最高值注释条形图。问题是 x 轴的坐标没有值,它有文本。

enter image description here

Python 熊猫 matplotlib 堆叠条形 绘图注释

评论


答:

1赞 some3128 11/14/2023 #1

下面的 data + 示例演示了如何标记最高的条形图。但是,它假设条形是直接使用的,并且数据是一个数组。如果您使用或其他一些绘图库生成绘图,则需要修改以下方法。matplotlibnumpypandas

enter image description here

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


#Synthetic data
np.random.seed(0)

month_names = pd.Series(
    pd.date_range(start='2023-01', periods=12, freq='M')
).dt.month_name().to_list()
month_names = [name[:3].upper() for name in month_names]

disturbances = np.stack([
    np.random.randn(12) * 4 + 50,  #orange bars
    np.random.randn(12) * 6 + 50], #blue bars
    axis=0
)
totals = disturbances.sum(axis=0) #total per month

#Plot
f, ax = plt.subplots(figsize=(10, 4))

bottom = np.zeros(12)
for dist in disturbances:
    bars = ax.bar(month_names, dist, bottom=bottom, label='')
    bottom += dist + 1.5

ax.xaxis.set_tick_params(rotation=45)
ax.set_xlabel('Month')
ax.set_ylabel('Disturbances')

#Make labels
#All labels empty except the largest value
labels = [''] * 12
labels[totals.argmax()] = totals[totals.argmax()].round()
ax.bar_label(bars, labels=labels);

0赞 Trenton McKinney 11/15/2023 #2
  • 柱线刻度位置通常索引为 0,尤其是在刻度标签是分类时。
  • 最简单的选择是使用 .pivot_table 聚合每个组的 ,并为相对于 的最大总柱线高度创建一个单独的变量。meantotindex
    • 索引将是 x 轴,列标题将是条形组。pivot_table
  • 熊猫。DataFrame.plot 和 提供了绘制堆积条的最简单选项。 用作默认绘图后端。kind='bar'stacked=Truepandasmatplotlib
  • 使用此答案和此答案中解释的.bar_label来注释条形图。
    • 该参数接受一个表达式,该表达式用于筛选标签以匹配 。这适用于 ,否则必须使用自定义参数,如链接的答案中所示。fmtlambdatotmatplotlib v3.7label
    • 每个颜色组的线段位于 中,其中是底部段,是顶部段。ax.containersax.containers[0]ax.containers[1]
    • label_type='edge'是默认值,这将导致注释是条形高度的总和。
  • 如果月份不是在 x 轴上排序的,则可以使用 pd 设置列。Categorical 和 .'month'ordered
    • from calendar import month_abbr以获取缩写月份名称的有序列表。
    • df.month = pd.Categorical(values=df.month, categories=month_abbr[1:], ordered=True)
  • python 3.12.0pandas 2.1.2、matplotlib 3.8.1seaborn 0.13.0 中测试
import seaborn as sns  # seaborn is only used for the sample data, but pandas and matplotlib are imported as dependencies
import numpy  # for sample data

# sample data: this is a pandas.DataFrame
df = sns.load_dataset('flights')[['month', 'passengers']]
np.random.seed(2023)
df['Gender'] = np.random.choice(['Male', 'Female'], size=len(df))

# pivot and aggregate the mean
pt = df.pivot_table(index='month', columns='Gender', values='passengers', aggfunc='mean')

# calculate the max value by the index
tot = pt.sum(axis=1).max()

# plot the stacked bars
ax = pt.plot(kind='bar', stacked=True, rot=0, figsize=(7, 5), xlabel='Month',
             ylabel='Mean Number of Passengers', title='Annotation Demonstration')

# annotate the top group of bars
ax.bar_label(ax.containers[1], fmt=lambda x: f'{x:0.0f}' if x == tot else '')

# move the legend: cosmetics
ax.legend(title='Gender', bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)

# remove the top and right spines: cosmetics
ax.spines[['top', 'right']].set_visible(False)

enter image description here

df.head()

  month  passengers  Gender
0   Jan         112  Female
1   Feb         118  Female
2   Mar         132    Male
3   Apr         129  Female
4   May         121  Female

pt

Gender      Female        Male
month                         
Jan     233.000000  259.250000
Feb     209.428571  270.800000
Mar     282.375000  245.750000
Apr     289.000000  245.166667
May     238.571429  318.400000
Jun     264.000000  378.400000
Jul     336.166667  366.500000
Aug     343.500000  358.666667
Sep     274.400000  322.428571
Oct     340.333333  192.833333
Nov     191.333333  274.333333
Dec     252.833333  270.833333

pt.sum(axis=1)

month
Jan    492.250000
Feb    480.228571
Mar    528.125000
Apr    534.166667
May    556.971429
Jun    642.400000
Jul    702.666667
Aug    702.166667
Sep    596.828571
Oct    533.166667
Nov    465.666667
Dec    523.666667
dtype: float64

tot

702.6666666666667