提问人:Ayman M 提问时间:11/14/2023 最后编辑:Trenton McKinneyAyman M 更新时间:11/15/2023 访问量:76
如何注释具有最大高度的堆叠条的顶部 [已关闭]
How to annotated the top of a stacked bar with the greatest height [closed]
问:
我有下面的图表,我想用最高值注释条形图。问题是 x 轴的坐标没有值,它有文本。
答:
1赞
some3128
11/14/2023
#1
下面的 data + 示例演示了如何标记最高的条形图。但是,它假设条形是直接使用的,并且数据是一个数组。如果您使用或其他一些绘图库生成绘图,则需要修改以下方法。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赞
Trenton McKinney
11/15/2023
#2
- 柱线刻度位置通常索引为 0,尤其是在刻度标签是分类时。
- 最简单的选择是使用
.pivot_table
聚合每个组的 ,并为相对于 的最大总柱线高度创建一个单独的变量。mean
tot
index
- 索引将是 x 轴,列标题将是条形组。
pivot_table
- 索引将是 x 轴,列标题将是条形组。
熊猫。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]
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.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']]
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)
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
上一个:单通道队列系统仿真
评论