我想绘制堆叠条形图。前 3 个条是红色、黑色和蓝色,如下所示。
我想添加第四个条,它是红色、黑色和蓝色条的值的“总和”。
(在另一种情况下,我想添加第四个条,它是红色、黑色和蓝色条的“平均值”。)
例如,这是我的代码:
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 个条有什么建议吗?
np.histogram
计算每组的hist
和bin_edges
,计算每组的总和和平均值,并绘制条形图,因为您将拥有每个箱子的所有绝对值。
pandas.DataFrame
和 pandas.DataFrame.plot
.
测试于
python 3.11.2
、pandas 2.0.1
、matplotlib 3.7.1
、numpy 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
h0, _ = np.histogram(x[:, 0], bins=be, density=True)
h1, _ = np.histogram(x[:, 1], bins=be, density=True)
h2, _ = np.histogram(x[:, 2], bins=be, density=True)
# stack the arrays for each bin group; same as np.column_stack
groups = np.c_[h0, h1, h2]
# calculate the total
tot = groups.sum(axis=1)
# calculate the mean
mean = groups.mean(axis=1)
# create a dataframe from the data and calculated groups
data = {'s0': h0, 's1': h1, 's2': h2, 'tot': tot, 'mean': mean}
be = be.round(1) # round the values of the bin edges
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 right 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)
.iloc
或 y=['s0', 's1', 's2', 'mean']
选择要绘制的特定列。ax = df.iloc[:, [0, 1, 2, 4]].plot(kind='bar', width=0.85, ec='k', figsize=(11, 6), rot=0)
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)