在条形图中注释单个条形Python

问题描述 投票:0回答:2

我有一个如下所示的图表,我想注释具有最高值的条形。问题是x轴的坐标,它没有值,它有测试。

python matplotlib annotations bar-chart
2个回答
0
投票

下面的数据+示例演示了如何标记最高的条形。但是,它假设条形图是直接使用

matplotlib
绘制的,并且数据是
numpy
数组。如果您使用
pandas
或其他绘图库生成绘图,则需要修改下面的方法。

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
投票
  • 最简单的选择是使用
    .pivot_table
    聚合每个组的
    mean
    ,并创建一个单独的变量
    tot
    表示相对于
    index
    的最大总条高度。
    • pivot_table
      索引将是 x 轴,列标题将是条形组。
  • pandas.DataFrame.plot
    kind='bar'
    stacked=True
    提供了绘制堆叠条形图的最简单选项。
    pandas
    使用
    matplotlib
    作为默认绘图后端。
  • 按照
    这个答案
    这个答案中的说明使用.bar_label来注释条形。
    • fmt
      参数是一个
      lambda
      表达式,用于过滤标签以匹配
      tot
      。这适用于
      matplotlib v3.7
      ,否则必须使用自定义
      label
      参数。
    • 每个颜色组的段位于
      ax.containers
      中,其中
      ax.containers[0]
      是底部段,
      ax.containers[1]
      是顶部段。
  • 已在
    python 3.12.0
    pandas 2.1.2
    matplotlib 3.8.1
    seaborn 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']]
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, xlabel='Month',
             ylabel='Mean Number of Passengers', title='Annotation Demonstration', figsize=(7, 5))

# annotate the top group of bars
ax.bar_label(ax.containers[1], fmt=lambda x: f'${x:0.2f}' 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)

tips.head()

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

pt

Gender      Female        Male
month                         
Jan     264.000000  197.250000
Feb     212.333333  257.666667
Mar     234.333333  306.000000
Apr     275.833333  258.333333
May     337.000000  206.666667
Jun     307.000000  318.200000
Jul     339.666667  363.000000
Aug     324.000000  389.000000
Sep     274.200000  322.571429
Oct     243.833333  289.333333
Nov     233.571429  231.800000
Dec     183.500000  277.500000
© www.soinside.com 2019 - 2024. All rights reserved.