我正在尝试创建一个比例堆积条形图,其中包含 (6) 个类别,总计为 100。我有一个数据框,其中六个类别 (C1) 中的每个类别都有一年中每个月的多个值 (n = 12) 、C2、C3、C4、C5、C6)。
我尝试使用 matplotlib m.patches 来组装每个条形的平均值,并得出下图。我想将每个条形堆叠在一起。目前,它们彼此叠放。
是否有任何简单的添加/修改可以让我堆叠条形?
代码和尝试的条形图:
# import libraries
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
df = pd.read_csv('marsh fig 7.csv')
plt.rcParams["axes.labelsize"] = 12
plt.figure(figsize=(600/my_dpi, 300/my_dpi), dpi=my_dpi)
bar1 = sns.barplot(x="Month", y="Percent_C1", data=df, color='darkgreen')
bar2 = sns.barplot(x="Month", y="Percent_C2", data=df, color='mediumseagreen')
bar3 = sns.barplot(x="Month", y="Percent_C3", data=df, color='goldenrod')
bar4 = sns.barplot(x="Month", y="Percent_C4", data=df, color='sienna')
bar5 = sns.barplot(x="Month", y="Percent_C5", data=df, color='steelblue')
bar6 = sns.barplot(x="Month", y="Component Proportion", data=df, color='darkblue')
# add legend
bar1 = mpatches.Patch(color='darkgreen', label='% C1')
bar2 = mpatches.Patch(color='mediumseagreen', label='% C2')
bar3 = mpatches.Patch(color='goldenrod', label='% C3')
bar4 = mpatches.Patch(color='sienna', label='% C4')
bar5 = mpatches.Patch(color='steelblue', label='% C5')
bar6 = mpatches.Patch(color='darkblue', label='% C6')
plt.ylim(0,40)
plt.text(0, 39, "Marsh", ha='left', va='top',fontsize=12, fontweight='normal', color="black")
ax2 = plt.twinx()
df2 = pd.read_csv('SRS1 Water Level.csv')
ax = sns.pointplot(x="Month", y="Water Depth (cm)", data=df2, color="black", linestyles=':', label=None, errwidth=1, capsize=0.2)
plt.legend(handles=[bar1, bar2, bar3, bar4, bar5, bar6])
plt.show()
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(20240801)
values = np.random.randint(1, 9, (12, 6)) # Fake some data
m = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split()
colors = 'darkgreen mediumseagreen goldenrod sienna steelblue darkblue'.split()
# equivalent to data = open('….csv').read()
data = '\n'.join(
['Month C1 C2 C3 V4 C5 C6'] +
[mon+' '+' '.join(str(v) for v in val) for mon, val in zip(m, values)]
)
# reorder data as "read" from file into a dictionary
labels, *data = [line.strip().split() for line in data.split('\n') if line]
month, *cn = labels
data = dict(zip(labels, zip(*data)))
# convert list of strings to arrays of floats
for c in cn: data[c] = np.array(data[c]).astype(float)
############################################################################
# Here it is the actual answer to your question as I've understood it
bottom = np.zeros(len(data[c]))
totals_by_month = np.array([sum(data[c][n] for c in cn) for n in range(12)])
for label in cn:
values = data[label]/totals_by_month
plt.bar(data[month], values,
label=label, bottom=bottom, ec='k', lw=0.5, color=colors.pop(0))
bottom += values
plt.legend()
plt.show()