首先我們的資料如下
import pandas as pd
data = pd.read_excel("rawdata.xlsx")
接著我們要將我們的資料,整理成方便我們繪圖的DataFrame
#先建立一個要存放我們繪圖要使用的DataFrame
dataFinal = pd.DataFrame()
dataFinal["量度"]=["非常不同意","不同意","普通","同意","非常同意"]
#將我們要繪製的每一題做一個迴圈,去計算它們的百分比值
for i in ["學習狀況良好","體育狀況良好","人際狀況良好"]:
#建立一個樞紐分析表,去紀錄各量度的個數
dataPvt = data[[i,"姓名"]].pivot_table(index=i,aggfunc="count").reset_index()
dataPvt.rename(columns={i:"量度"},inplace=True)
#寫一個轉換函數,建立一個排序值的欄位,以此進行排序
def word2num(x):
if x == "非常同意": return 5
elif x == "同意": return 4
elif x == "普通": return 3
elif x == "不同意": return 2
elif x == "非常不同意": return 1
dataPvt["排序值"] = list(map(lambda x : word2num(x),dataPvt["量度"]))
dataPvt.sort_values(by="排序值",inplace=True)
#建立一個百分比值的欄位
dataPvt[i] = list(map(lambda x: ((x/dataPvt["姓名"].sum())*100),dataPvt["姓名"]))
#將百分比值欄位添加進繪圖要使用的DataFrame
dataFinal[i] = dataPvt[i]
#將DataFrame中的遺漏值補為0
dataFinal.fillna(0,inplace=True)
有了這樣的資料,我們就可以開始繪製百分比堆疊直條圖了:
import matplotlib
#選擇中文字體
matplotlib.rc("font",family="Microsoft YaHei")
from matplotlib import pyplot as plt
#繪製圖的大小
plt.figure(figsize=(8,4))
#繪製一個位於包含1X1個子圖的圖且位置在(0,0)的子圖
ax0 = plt.subplot2grid((1,1),(0,0),colspan=1,rowspan=1)
#--------------------------------
#建立x軸資料
ax0_x = dataFinal.columns.values.tolist()
ax0_x.remove("量度")
#建立h軸資料來源(因為我們從中取出不同的資料作堆疊)
ax0_h_source = dataFinal.drop(columns="量度")
#建立稍候迴圈堆疊時會用到的變數
start = 0
colorList = ["darkred","red","darkgray","green","darkgreen"]
#--------------------------------
#開始繪製Bar
for i, color_value, label_value in zip(range(0,5),colorList,["非常不同意","不同意","普通","同意","非常同意"]):
#從h軸資料來源中取出1行作為h軸資料
ax0_h = ax0_h_source.loc[i]
#left是指起始位置,讓它從0開始
ax0.barh(ax0_x,ax0_h,height=0.5,left=start,color=color_value,label=label_value)
#讓下一次繪圖時的起始值,加上這次h的值,以此做堆疊
start = start + ax0_h
#利用迴圈,加上數值資訊
for k,r,j in zip(start,range(0,len(list(ax0_x))),ax0_h):
if j!=0:
ax0.text(k-j/2, r, str(round(j)) + "%", color="white", horizontalalignment="center",verticalalignment="center",fontsize=10)
elif j == 0:
ax0.text(k-j/2, r, "", color="white", horizontalalignment="center",verticalalignment="center",fontsize=10)
#--------------------------------
#讓x軸座標與刻度不顯現
ax0.set_xticklabels([])
ax0.set_xticks([])
#建立圖例資訊
ax0.legend(ncols=5, loc="lower center",bbox_to_anchor=(0.5,-0.15))
#建立標題
plt.title("百分比堆疊直條圖")