numpy 如何计算每个直方图条的总和和平均值

q9yhzks0  于 2023-05-22  发布在  其他
关注(0)|答案(1)|浏览(139)

我想绘制堆叠条形图。前3个条形图为红色、黑色和蓝色,如下所示。
我想添加一个第四条,它是红色,黑色和蓝色条值的“总和”。
(In在另一种情况下,我想添加第四个条形,即红、黑、蓝条形的“平均值”。)
例如,这是我的代码:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(19680801)

n_bins = 20
x = np.random.randn(1000, 3)

fig, ax0 = plt.subplots(nrows=1, ncols=1)

colors = ['red', 'black', 'blue']
ax0.hist(x, n_bins, density=True, histtype='bar', color=colors, label=colors)
ax0.legend(prop={'size': 10})
ax0.set_title('bars with legend')


fig.tight_layout()
plt.show()

这个数字不包括第四条。

任何建议如何我可以显示在这个堆栈条形图第4条?

klsxnrf1

klsxnrf11#

使用np.histogram计算每组的histbin_edges,计算每组的总和和平均值,并使用每个箱的绝对条形高度绘制条形图。
绘制分组或堆叠条形图的最简单方法是从pandas.DataFramepandas.DataFrame.plot

python 3.11.2pandas 2.0.1matplotlib 3.7.1numpy 1.24.3中测试

import numpy as np
import pandas as pd

# data
np.random.seed(19680801)
n_bins = 20
x = np.random.randn(1000, 3)

# calculate bin_edges for the combined values
_, be = np.histogram(x, bins=n_bins, density=True)

# calculate hist for each sample
data = {f's{i}': np.histogram(col, bins=be, density=True)[0] for i, col in enumerate(x.T)}

# round the values of the bin edges to be used as xtick labels in the plot
be = be.round(1)

# stack the arrays for each bin group
groups = np.column_stack(list(data.values()))

# calculate the total
data['tot'] = groups.sum(axis=1)

# calculate the mean
data['mean'] = groups.mean(axis=1)

# create a dataframe from data
df = pd.DataFrame(data=data)

# plot 
ax = df.plot(kind='bar', width=0.85, ec='k', figsize=(11, 6), rot=0)

# update the xticks by shifting them to the left by 0.5, and updating the labels
ax.set_xticks(ticks=np.arange(0, len(be))-0.5, labels=be)

# add some cosmetics
ax.grid(axis='x')
ax.spines[['right', 'top']].set_visible(False)
_ = ax.legend(bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)

  • 使用.ilocy=['s0', 's1', 's2', 'mean']选择要打印的特定列。
# plot 
ax = df.iloc[:, [0, 1, 2, 4]].plot(kind='bar', width=0.85, ec='k', figsize=(14, 6), rot=0)

# add some cosmetics
ax.set_xticks(ticks=np.arange(0, len(be))-0.5, labels=be)
ax.grid(axis='x')
ax.spines[['right', 'top']].set_visible(False)
_ = ax.legend(bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)

# add some labels
for c in ax.containers:
    ax.bar_label(c, fmt=lambda x: f'{x:0.3f}' if x > 0.005 else '', label_type='edge', fontsize=6, rotation=90, padding=3)
    
ax.margins(y=0.15)

相关问题