普通高中選課數(shù)據(jù)分析和可視化(3)
前情回顧:
3.5 繪制各學(xué)科關(guān)聯(lián)度散點圖
和前面幾個圖表不一樣,這里不需要對df按學(xué)校分組計數(shù),而是構(gòu)造一個反映各學(xué)科關(guān)聯(lián)度的DataFrame對象zuhe(所謂關(guān)聯(lián)度就是某學(xué)生同時選擇了該兩個科目),再遍歷每一門學(xué)科,繪制其與其他學(xué)科關(guān)聯(lián)度散點圖。我們既可以在同一個區(qū)域繪制各學(xué)科關(guān)聯(lián)度散點圖,也可以分成多個子圖,分別繪制各學(xué)科關(guān)聯(lián)度散點圖(如下圖所示)。
圖9 各學(xué)科關(guān)聯(lián)度散點圖

圖10 各學(xué)科關(guān)聯(lián)度散點圖(多子圖)
核心代碼(完整代碼詳見源代碼文件“7選3繪制各學(xué)科關(guān)聯(lián)度散點圖.py”):
#在同一個區(qū)域繪制各學(xué)科關(guān)聯(lián)度散點圖colors = ('red','green','orange','cyan','lime','gold','blue')fig, ax = plt.subplots(figsize=(10,12),dpi=120)for i, k in enumerate(kms, start=0): #遍歷每一門學(xué)科,繪制其與其他學(xué)科關(guān)聯(lián)度散點圖nums = zuhe.loc[k].tolist()area = [j*0.2 for j in nums]ax.scatter(x=kms,y=nums,s=area,c=colors[i],label=k,alpha=0.5)ax.legend()#分別繪制各學(xué)科關(guān)聯(lián)度散點圖plt.figure(figsize=(10,10),dpi=120) #生成新的figure,并設(shè)置各個子圖的寬、高和繪圖分辨率for i, k in enumerate(kms, start=1): #遍歷每一門學(xué)科,繪制其與其他學(xué)科關(guān)聯(lián)度散點圖#subplot將整個繪圖區(qū)域等分為Rows行*Cols列個子區(qū)域,按照從左到右,從上到下的順序?qū)γ總€子區(qū)域進行編號plt.subplot(3, 3, i) #劃分子圖,分成3*3個區(qū)域plt.subplots_adjust(hspace = 0.5) #為子圖之間的空間保留的高度plt.title(f"{k}散點圖") #為每個子圖設(shè)置標(biāo)題nums = zuhe.loc[k].tolist()area = [j*0.1 for j in nums]plt.scatter(x=kms,y=nums,s=area,alpha=0.5)plt.show()
3.6 7選3選課組合數(shù)據(jù)處理
標(biāo)準(zhǔn)庫中的itertools包提供了很多靈活的生成循環(huán)器的工具,主要分為無限迭代器、輸入序列迭代器、組合生成器。其中函數(shù)combinations(iterable,r)屬于組合生成器,用來生成指定數(shù)目r的元素不重復(fù)的所有組合。
我們使用語句import itertools引入庫,設(shè)置各科簡稱字符串kms = "物化生政史地技",然后生成選課組合名稱列表kmzh_3 = [''.join(km) for km initertools.combinations(kms,3)];接下來打開"xk73.csv"文件,讀取某市普通高中選課匯總數(shù)據(jù),存儲到DataFrame對象df中;再遍歷每一所學(xué)校,為每位學(xué)生生成選課組合信息,并統(tǒng)計各校各選課組合數(shù)量(如下圖所示)。

圖11 各校各選課組合人數(shù)統(tǒng)計圖
核心代碼(完整代碼詳見源代碼文件“7選3選課組合數(shù)據(jù)處理.py”):
kms = "物化生政史地技"kmzh_3 = [''.join(km) for km in itertools.combinations(kms,3)]kms_dic = {"物理":"物","化學(xué)":"化","生物":"生","政治":"政","歷史":"史","地理":"地","技術(shù)":"技"}#讀數(shù)據(jù)到 Pandas的DataFrame 結(jié)構(gòu)中source_df =pd.read_csv("xk73.csv",sep=',',header='infer',encoding='utf-8')schools = sorted(source_df['學(xué)校代碼'].unique()) #生成學(xué)校代碼名稱列表zuhe_df = pd.DataFrame(index=schools, columns=kmzh_3)
3.7 繪制各校各選課組合人數(shù)柱狀圖
我們統(tǒng)計好各校各選課組合數(shù)據(jù)以后,就可以調(diào)用DataFrame.plot方法繪制各校各選課組合人數(shù)堆積柱狀圖了,還可以分成多個子圖,分別繪制各校各選課組合人數(shù)柱狀圖(如下圖所示)。

圖12 各校各選課組合人數(shù)堆積柱狀圖

圖13 各校各選課組合人數(shù)柱狀圖(多子圖)
核心代碼(完整代碼詳見源代碼文件“7選3選課組合數(shù)據(jù)可視化.py”):
#調(diào)用DataFrame.plot方法繪制全市各選課組合人數(shù)柱狀圖plt.bar(df_sum.columns, df_sum.loc[0])plt.xticks(rotation = 90)x = list(range(len(df_sum.columns)))y = list(df_sum.loc[0])for a,b in zip(x, y): #控制標(biāo)簽位置plt.text(a,b+1.5,'%.0f'%b,ha = 'center',va = 'bottom')plt.show()
3.8 繪制各校各選課組合人數(shù)占比餅圖
和繪制柱狀圖一樣,我們需要先統(tǒng)計好各校各選課組合數(shù)據(jù),再分別去繪制各校各選課組合人數(shù)占比餅圖(如下圖所示)。

圖14 各校各選課組合人數(shù)占比餅圖(多子圖)
核心代碼(完整代碼詳見源代碼文件“7選3選課組合數(shù)據(jù)可視
化.py”):
#分別繪制各校各選課組合人數(shù)占比餅圖i = 1for r in zuhe_df.index: #遍歷每一所學(xué)校,繪制各校各選課組合人數(shù)占比餅圖if i % 4 == 1: #每頁生成4張子圖,每畫完4張子圖就生成新的窗體plt.figure(figsize=(10,10),dpi=70) #生成新的figure,并設(shè)置各個子圖的寬、高和繪圖分辨率i = 1#subplot將整個繪圖區(qū)域等分為Rows行*Cols列個子區(qū)域,按照從左到右,從上到下的順序?qū)γ總€子區(qū)域進行編號plt.subplot(2, 2, i) #劃分子圖,分成2*2個區(qū)域i += 1plt.subplots_adjust(hspace = 0.5) #為子圖之間的空間保留的高度plt.title(f"學(xué)校{r}各選課組合人數(shù)") #為每個子圖設(shè)置標(biāo)題plt.xticks(fontsize=10) #標(biāo)簽字體大小show_zuhe_df = zuhe_df.sort_values(by=r, axis=1, ascending=False)zuhe_nums = 9 #只輸出人數(shù)最多的前9個組合show_zuhe_df.insert(zuhe_nums, '其他', show_zuhe_df.loc[r, show_zuhe_df.columns[zuhe_nums:]].sum()) #插入其他列labels = show_zuhe_df.columns[:zuhe_nums+1]sizes = show_zuhe_df.loc[r, show_zuhe_df.columns[:zuhe_nums+1]]explode = [0] * len(sizes)explode[-1] = 0.1plt.pie(sizes,explode=explode,labels=labels,autopct='%1.1f%%',shadow=False)plt.show()
說明:因為本項目內(nèi)容較多,故寫成系列文章分成多次分享,請大家稍安勿躁哦。
需要本文word版或者相關(guān)源代碼的,可以加入“Python算法之旅”知識星球參與討論和下載文件,“Python算法之旅”知識星球匯集了數(shù)量眾多的同好,更多有趣的話題在這里討論,更多有用的資料在這里分享。
我們專注Python算法,感興趣就一起來!
相關(guān)優(yōu)秀文章:
