【matplotlib 實戰】--堆疊柱狀圖

2023-10-10 12:02:46

堆疊柱狀圖,是一種用來分解整體、比較各部分的圖。
與柱狀圖類似,堆疊柱狀圖常被用於比較不同類別的數值。而且,它的每一類數值內部,又被劃分為多個子類別,這些子類別一般用不同的顏色來指代。

柱狀圖幫助我們觀察「總量」,堆疊柱狀圖則可以同時反映「總量」與「結構」。
也就是說,堆疊柱狀圖不僅可以反映總量是多少?還能反映出它是由哪些部分構成的?
進而,我們還可以探究哪一部分比例最大,以及每一部分的變動情況,等等。

1. 主要元素

堆疊柱狀圖是常用於比較多個類別或組之間的資料。
它通過將多個柱狀圖堆疊在一起,展示每個類別或組的總量以及各個部分的相對比例。

它的主要構成元素包括:

  1. 橫軸:表示資料的主分類。
  2. 縱軸:每個子分類的比例關係。
  3. 堆疊的矩形:每個柱狀圖由多個堆疊部分組成,每個堆疊部分表示該類別或組中的一個部分或子類別。
  4. 圖例:每個堆疊部分代表的意義。

2. 適用的場景

堆疊柱狀圖適用於以下的分析場景:

  • 比較多個類別或組的總量以及各個部分的相對比例,例如不同產品的銷售總額以及各個渠道的銷售額佔比。
  • 視覺化多個類別或組的趨勢變化,例如不同地區的人口數量隨時間的變化趨勢。
  • 對比多個類別或組之間的差異,例如不同年份的營業額對比。

3. 不適用的場景

堆疊柱狀圖不適用以下的分析場景:

  • 資料具有負值或包含缺失值的情況。堆疊柱狀圖只適用於展示正值資料,不適合包含負值或缺失值的資料。
  • 需要比較多個類別的絕對數值大小。堆疊柱狀圖主要關注各個部分的相對比例,而不是絕對數值大小的比較。

4. 分析實戰

本次用堆疊柱狀圖統計最近幾年全國居民消耗的主要幾類糧食的情況。

4.1. 資料來源

資料來自國家統計局公開的人民生活資料,可從下面的網址下載:
https://databook.top/nation/A0A

使用的是其中 A0A0A.csv檔案(全國居民主要食品消費量)

fp = "d:/share/A0A0A.csv"

df = pd.read_csv(fp)
df

4.2. 資料清理

本次繪製堆疊柱狀圖,時間上選擇最近幾年的資料,由於2022年的資料缺失,選擇** 2013年~2021年的資料。
內容上每個年度選擇
5類**常見的食物:

  1. 居民人均蔬菜及食用菌消費量(千克)
  2. 居民人均肉類消費量(千克)
  3. 居民人均禽類消費量(千克)
  4. 居民人均水產品消費量(千克)
  5. 居民人均蛋類消費量(千克)
#> A0A0A03 居民人均蔬菜及食用菌消費量(千克)
#> A0A0A04 居民人均肉類消費量(千克)
#> A0A0A05 居民人均禽類消費量(千克)
#> A0A0A06 居民人均水產品消費量(千克)
#> A0A0A07 居民人均蛋類消費量(千克)
data = df[(df["sj"] >= 2013) & 
        (df["sj"] <= 2021) & 
        (df["zb"].isin(["A0A0A03", 
                        "A0A0A04",
                        "A0A0A05",
                        "A0A0A06",
                        "A0A0A07"]))].copy()

data.head(10)

一共45條資料,5個分類,每個分類有9個年度的資料。

4.3. 分析結果視覺化

data = data.sort_values("sj")
data[data["zb"] == "A0A0A03"]["value"].tolist()


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"]["value"].tolist(),
        "肉類(千克)": data[data["zb"] == "A0A0A04"]["value"].tolist(),
        "禽類(千克)": data[data["zb"] == "A0A0A05"]["value"].tolist(),
        "水產品(千克)": data[data["zb"] == "A0A0A06"]["value"].tolist(),
        "蛋類(千克)": data[data["zb"] == "A0A0A07"]["value"].tolist(),
    }

    bottom = np.zeros(len(years))
    for key, vals in bar_data.items():
        ax.bar(years, vals, label=key, bottom=bottom)
        bottom += vals

    ax.set_title("全國居民主要糧食消耗情況")
    ax.legend(loc="upper left", ncol=3)

看圖中的分析結果,和事先預想的差不多,蔬菜肉類是我們平時主要的糧食來源。
圖中還可以看出,在3年疫情期間,糧食消耗逐步增多,可能是大家認為吃的好才能增強抵抗力 :)