百分比堆疊式柱狀圖是一種特殊的柱狀圖,它的每根柱子是等長的,總額為100%。
柱子內部被分割為多個部分,高度由該部分佔總體的百分比決定。
百分比堆疊式柱狀圖不顯示資料的「絕對數值」,而是顯示「相對比例」。
但同時,它也仍然具有柱狀圖的固有功能,即「比較」——我們可以通過比較多個柱子的構成,分析數值之間的相對差異,或者得出數值變化的趨勢。
百分比柱狀圖是一種用於視覺化比較不同類別或組的百分比或比例的圖表。
它的主要元素包括:
百分比柱狀圖適用的場景很多,比如:
百分比柱狀圖也有不適用於的場景,比如:
和上一篇堆疊柱狀圖使用相同的原始資料,繪製圖形之後可以看看這兩種柱狀圖展示分析結果的區別。
資料來自國家統計局公開的人民生活資料,可從下面的網址下載:
https://databook.top/nation/A0A
使用的是其中 A0A0A.csv
檔案(全國居民主要食品消費量)
fp = "d:/share/A0A0A.csv"
df = pd.read_csv(fp)
df
選取和上一篇堆疊柱狀圖一樣,還是5類:
和堆疊柱狀圖不同的是,繪製百分比柱狀圖用的是百分比數值,
所有要把原始資料中每年的絕對數值轉換為百分比數值。
data = df[(df["sj"] >= 2013) &
(df["sj"] <= 2021) &
(df["zb"].isin(["A0A0A03",
"A0A0A04",
"A0A0A05",
"A0A0A06",
"A0A0A07"]))].copy()
data["年消耗總量"] = data.groupby("sj").value.transform("sum")
data["各類消耗量佔比"] = data["value"] / data["年消耗總量"]
data.loc[:, ["sjCN", "zbCN", "各類消耗量佔比"]].head(10)
import matplotlib.ticker as mticker
data = data.sort_values("sj")
data["各類消耗量佔比"] = data["各類消耗量佔比"]*100
with plt.style.context("seaborn-v0_8"):
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
years = data["sjCN"].drop_duplicates(keep="first").tolist()
bar_data = {
"蔬菜及菌類(%)": data[data["zb"] == "A0A0A03"]["各類消耗量佔比"].tolist(),
"肉類(%)": data[data["zb"] == "A0A0A04"]["各類消耗量佔比"].tolist(),
"禽類(%)": data[data["zb"] == "A0A0A05"]["各類消耗量佔比"].tolist(),
"水產品(%)": data[data["zb"] == "A0A0A06"]["各類消耗量佔比"].tolist(),
"蛋類(%)": data[data["zb"] == "A0A0A07"]["各類消耗量佔比"].tolist(),
}
bottom = np.zeros(len(years))
for key, vals in bar_data.items():
ax.bar(years, vals, label=key, bottom=bottom)
bottom += vals
# 設定Y軸刻度的顯示格式
ax.set_ylim(0, 110)
yticks = ax.get_yticks().tolist()
ax.yaxis.set_major_locator(mticker.FixedLocator(yticks))
ax.set_yticklabels(["{}%".format(x) for x in yticks])
ax.set_title("全國居民主要糧食消耗情況")
ax.legend(loc="upper left", ncol=5)
百分比柱狀圖每年的資料高度都一樣,與堆疊柱狀圖相比,更容易比較每個種類糧食的消耗情況。
不過,這種圖看不出糧食總量的變化情況了。