看了这个总结,其实 Matplotlib 可视化,也没那么难!
作者 |?舊時晚風拂曉城? ? ? ?編輯?| JackTian
來源 | 杰哥的IT之旅(ID:Jake_Internet)
Python 中可以通過 matplotlib 模塊的 pyplot 子庫來完成繪圖。Matplotlib 可用于創建高質量的圖表和圖形,也可以用于繪制和可視化結果。matplotlib 是 Python 優秀的數據可視化第三方庫,matplotlib.pyplot 是繪制種類可視化圖形的命令子庫,相當于快捷方式 import matplotlib.pyplot as plt.
本文用 Python 對一批運動員數據進行操作,讀取數據、數據預處理、matplotlib 數據可視化,熟悉用 Python 進行數據分析和可視化的基本方法,并繪制柱形圖、堆疊圖、折線圖、餅圖、環圖、箱形圖、散點圖、直方圖、多個子圖和熱力圖。
數據集部分截圖如下:
pandas讀取并查看數據,對于本次練習的數據,讀取時需要設置encoding='gbk',不然會報錯。
pd.read_csv()讀取csv文件,數據有17587行,17列。
import?pandas?as?pddf?=?pd.read_csv('soccer.csv',?encoding='gbk') print(df)df.info():查看索引、數據類型和內存信息
import?pandas?as?pddf?=?pd.read_csv('soccer.csv',?encoding='gbk') print(df.info())df.describe():查看數值型列的匯總統計情況
import?pandas?as?pddf?=?pd.read_csv('soccer.csv',?encoding='gbk') print(df.describe())pyplot中文顯示:
pyplot并不默認顯示中文,坐標系中出現中文漢字,需要增加額外代碼輔助。
方法一:
可以通過rcParams修改字體實現,但這種方法改變的是全局的字體。
import?matplotlib?as?mplmpl.rcParams['font.family']?=?'SimHei' mpl.rcParams['font.size']?=?15方法二:
在有中文輸出的地方,增加一個屬性:fontproperties
import?matplotlib.pyplot?as?plt import?numpy?as?npa?=?np.arange(0.0,?5.0,?0.02) plt.figure(figsize=(9,?6),?dpi=100) plt.plot(a,?np.cos(2?*?np.pi?*?a),?'r--') #?在特定的地方用中文??和改變字號 plt.xlabel('橫軸:時間',?fontproperties='SimHei',?fontsize=15,?color='green') plt.ylabel('縱軸:振幅',?fontproperties='SimHei',?fontsize=15,?color='red') plt.show()1. 繪制柱形圖
(1) ?將運動員年齡(Age)劃分為三個年齡段:’17-26’,’27-36’,’37-47’,統計不同年齡段的人數,并用柱狀圖可視化。
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib?as?mpl#?讀取數據??設置編碼??不然會報錯 df?=?pd.read_csv('soccer.csv',?encoding='gbk') #?將運動員年齡(Age)劃分為三個年齡段 age_group?=?["17-26",?"27-36",?"37-47"] #?統計不同年齡段人數 count_1?=?df[(df['Age']?>=?17)?&?(df['Age']?<=?26)] count_2?=?df[(df['Age']?>=?27)?&?(df['Age']?<=?36)] count_3?=?df[(df['Age']?>=?37)?&?(df['Age']?<=?47)] age_counts?=?[len(count_1),?len(count_2),?len(count_3)]#?設置大小???像素 plt.figure(figsize=(9,?6),?dpi=100) #?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei' #?繪制柱形圖??設置柱條的寬度和顏色 plt.bar(age_group,?age_counts,?width=0.35,?color='red') #?添加描述信息 plt.title('不同年齡段人數統計') plt.xlabel('年齡段') plt.ylabel('人數') #?可以設置網格??透明度?線條樣式 plt.grid(alpha=0.3,?linestyle=':') #?展示圖片 plt.show()(2) 查看不同技術等級(Skill_Moves )下的球員數量,以及哪個技術等級的球員數量最多,哪個最少,利用水平柱狀圖可視化。
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib?as?mpldf?=?pd.read_csv('soccer.csv',?encoding='gbk') skill_count?=?df['Skill_Moves'].value_counts()skill?=?[f'等級{m}'?for?m?in?skill_count.index]????#?列表推導式構造不同技術等級 counts?=?skill_count.values.tolist()???????????????#?技術等級對應人數統計的列表#?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei' #?設置大小??像素 plt.figure(figsize=(9,?6),?dpi=100) #?繪制水平柱狀圖 plt.barh(skill[::-1],?counts[::-1],?height=0.5,?color='#FF00FF') plt.title('不同技術等級人數統計') plt.xlabel('人數') plt.show()2. 繪制堆疊圖
將運動員年齡(Age)劃分為三個年齡段:’17-26’,’27-36’,’37-47’,統計 3 個年齡段下 5個技術等級(Skill_Moves)的人數,并用堆疊圖可視化。
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?collections import?numpy?as?np import?matplotlib?as?mpldf?=?pd.read_csv('soccer.csv',?encoding='gbk') age_group?=?["17-26",?"27-36",?"37-47"]#?&?與????|?或???不同條件之間?()括起來 data1?=?df[(17?<=?df['Age'])?&?(df['Age']?<=?26)] age1?=?list(data1['Skill_Moves']) data2?=?df[(27?<=?df['Age'])?&?(df['Age']?<=?36)] age2?=?list(data2['Skill_Moves']) data3?=?df[(37?<=?df['Age'])?&?(df['Age']?<=?47)] age3?=?list(data3['Skill_Moves'])#?分別統計三個年齡段?不同等級人數 count_1?=?collections.Counter(age1).most_common() count_2?=?collections.Counter(age2).most_common() count_3?=?collections.Counter(age3).most_common() count_3.append((5,?0))????#?37-47年齡段等級5人數為零??手動添上counts?=?count_1?+?count_2?+?count_3 datas?=?[[]?for?i?in?range(5)] for?i?in?counts:datas[i[0]?-?1].append(i[1])#?轉化為數組??堆疊時可以對應相加 grades?=?np.array(datas) #?print(grades) #?設置大小???像素 plt.figure(figsize=(9,?6),?dpi=100) #?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei'plt.bar(age_group,?grades[0],?label='等級一',?color='red',?width=0.35) plt.bar(age_group,?grades[1],?bottom=grades[0],?label="等級二",?color="#9400D3",?width=0.35) plt.bar(age_group,?grades[2],?bottom=grades[0]?+?grades[1],?label="等級三",?color="#0000FF",?width=0.35) plt.bar(age_group,?grades[3],?bottom=grades[0]?+?grades[1]?+?grades[2],?label="等級四",?color="#FFFF00",?width=0.35) plt.bar(age_group,?grades[4],?bottom=grades[0]?+?grades[1]?+?grades[2]?+?grades[3],?label="等級五",?color="#006400",?width=0.35)plt.title('不同年齡段等級人數統計') plt.xlabel('年齡段') plt.ylabel('人數') plt.grid(alpha=0.3,?linestyle=':') #?顯示圖例?位置 plt.legend(loc=0) plt.show()3. 繪制折線圖
利用頻數分布折線圖來查看運動員身高(Height)與體重(Weight)的分布
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib.gridspec?as?gridspec import?matplotlib?as?mpldf?=?pd.read_csv('soccer.csv',?encoding='gbk')#?<class?'pandas.core.series.Series'> height?=?df['Height'].value_counts() weight?=?df['Weight'].value_counts() #?SeriseL類型通過索引進行排序??也就是按身高從低到高排序 heights?=?height.sort_index() weights?=?weight.sort_index()mpl.rcParams['font.family']?=?'SimHei' gs?=?gridspec.GridSpec(1,?2) plt.figure(figsize=(12,?5),?dpi=100) #?設置圖形顯示風格 plt.style.use('ggplot') ax1?=?plt.subplot(gs[0,?0]) ax2?=?plt.subplot(gs[0,?1])#?子圖1 ax1.plot(heights.index,?heights.values) ax1.set_title('運動員身高頻數分布折線圖') ax1.set_xlabel('身高(cm)') ax1.set_ylabel('人數') #?子圖2 ax2.plot(weights.index,?weights.values) ax2.set_title('運動員體重頻數分布折線圖') ax2.set_xlabel('體重(kg)') ax2.set_ylabel('人數')plt.show() 在這里插入圖片描述4. 繪制餅圖
(1) 使用餅圖查看運動員的慣用腳(Preffered_Foot)字段中不同慣用腳人數的占比。
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib?as?mplpreffered_foot?=?list(pd.read_csv('soccer.csv',?encoding='gbk')['Preffered_Foot']) foot?=?['右腳',?'左腳'] counts?=?[preffered_foot.count('Right'),?preffered_foot.count('Left')]#?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei' #?設置大小??像素 plt.figure(figsize=(9,?6),?dpi=100) plt.axes(aspect='equal')???#?保證餅圖是個正圓 explodes?=?[0,?0.2] color?=?['red',?'#00FF00'] #?繪制餅圖 # x:統計數據?? explode:是否突出顯示??? label:標簽? color:自定義顏色 # autopct:設置百分比的格式,保留2位小數? shadow:??有陰影??看起來立體 # startangle:初始角度?可使餅圖旋轉????? labeldistance:標簽離圓心的位置 plt.pie(counts,?explode=explodes,?labels=foot,colors=color,?autopct='%.2f%%',?shadow=True,startangle=15,?labeldistance=0.8,) plt.title('不同慣用腳的運動員人數占比圖',?fontsize=15) plt.show()(2) 按照運動員的技術等級(Skill_Moves),使用環圖展示出運動員不同技術等級人數的占比。
import?pandas?as?pd import?collections import?matplotlib.pyplot?as?plt import?matplotlib?as?mplskill_moves?=?list(pd.read_csv('soccer.csv',?encoding='gbk')['Skill_Moves']) skill_count?=?collections.Counter(skill_moves).most_common()skill?=?['等級{}'.format(m[0])?for?m?in?skill_count] counts?=?[n[1]?for?n?in?skill_count]#?設置大小??像素 plt.figure(figsize=(9,?6),?dpi=100) #?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei' plt.axes(aspect='equal')???#?保證餅圖是個正圓 x_?=?[1,?0,?0,?0,?0]???????#?用于顯示空心 color?=?["red",?"blue",?"yellow",?"green",?"purple"]plt.pie(x=counts,?colors=color,?pctdistance=0.9,startangle=45,?autopct='%.1f%%',?shadow=True,) #?小的空白圓填充??實現圓環效果 plt.pie(x_,?radius=0.65,?colors="w")#?添加圖例??可以微調位置 plt.legend(skill,?bbox_to_anchor=(0.9,?0.92)) plt.title('不同技術等級的運動員人數占比圖',?fontsize=15) plt.show()5. 繪制箱形圖
箱線圖,又稱箱形圖 (boxplot) 或盒式圖,不同于一般的折線圖、柱狀圖或餅圖等傳統圖表,只是數據大小、占比、趨勢等等的呈現,其包含一些統計學的均值、分位數、極值等等統計量,因此,該圖信息量較大,不僅能夠分析不同類別數據平均水平差異(需在箱線圖中加入均值點),還能揭示數據間離散程度、異常值、分布差異等等。
使用箱形圖展示出不同技術等級 (Skill_Moves) 的運動員的評分 (Rating) 分布情況,即橫軸為運動員的技術等級,縱軸為評分。
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib?as?mpldf?=?pd.read_csv('soccer.csv',?encoding='gbk') labels?=?[f'等級{i}'?for?i?in?['一',?'二',?'三',?'四',?'五']]data1?=?df[df['Skill_Moves']?==?1]['Rating'] data2?=?df[df['Skill_Moves']?==?2]['Rating'] data3?=?df[df['Skill_Moves']?==?3]['Rating'] data4?=?df[df['Skill_Moves']?==?4]['Rating'] data5?=?df[df['Skill_Moves']?==?5]['Rating']#?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei' #?設置圖形顯示風格 plt.style.use('ggplot') fig,?ax?=?plt.subplots() box_plot?=?ax.boxplot((data1,?data2,?data3,?data4,?data5),?labels=labels,boxprops={'color':?'black'},?showmeans=True,?patch_artist=True,)colors?=?['pink',?'blue',?'green',?'yellow',?'red']#?填充箱子顏色 for?patch,?color?in?zip(box_plot['boxes'],?colors):patch.set(facecolor=color)#?設置箱子兩端線的屬性 for?whisker?in?box_plot['whiskers']:whisker.set(color='purple',?linewidth=2) #?設置頂端和末端線條的屬性 for?cap?in?box_plot['caps']:cap.set(color='g',?linewidth=3) #?設置中位數的屬性 for?median?in?box_plot['medians']:median.set(color='black',?linewidth=3)plt.xlabel('技術等級') plt.ylabel('評分') plt.title('不同技術等級的運動員評分分布箱形圖')plt.show()6. 繪制散點圖
繪制年齡 (Age) 與評分 (Rating) 構成的散點圖
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib?as?mpldf=?pd.read_csv('soccer.csv',?encoding='gbk') age,?rating?=?list(df['Age']),?list(df['Rating'])#?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei' #?設置圖形顯示風格 plt.style.use('ggplot') #?設置大小??像素 plt.figure(figsize=(9,?6),?dpi=100)#?繪制散點圖 plt.scatter(age,?rating)#?添加描述信息 plt.title('運動員年齡與評分散點圖') plt.xlabel('年齡') plt.ylabel('評分') plt.show()7. 繪制直方圖
利用直方圖查看運動員的年齡(Age)分布
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib?as?mplages?=?list(pd.read_csv('soccer.csv',?encoding='gbk')['Age']) ages.sort()#?設置中文顯示 mpl.rcParams['font.family']?=?'SimHei' #?設置圖形顯示風格 plt.style.use('ggplot') plt.figure(figsize=(9,?6),?dpi=100)bin_width?=?1??#?設置組距???整除 num_bin?=?(max(ages)?-?min(ages))?//?bin_width????#?組數#?繪制直方圖? x:指定要繪制直方圖的數據 # bins:指定直方圖條形的個數? color:設置直方圖的填充色??? edgecolor:指定直方圖的邊界色 plt.hist(x=ages,?bins=num_bin,?color='blue',?edgecolor='k',?label='直方圖')???#?為直方圖呈現標簽 plt.xticks(range(20,?50,?5))?????#?設置x軸刻度#?添加描述信息 plt.xlabel('年齡區間') plt.ylabel('頻數') plt.title('年齡頻數分布直方圖')plt.legend() plt.show()數據可視化的時候,有時需要將多個子圖放在同一個畫板上進行比較。通過使用GridSpec類配合subplot,可以很容易對子區域進行劃定和選擇,在同一個畫板上繪制多個子圖。
8. 對子繪圖區域的劃定和選擇
GridSpec是matplotlib中一個特殊的用來進行子繪圖區域設計和選定的一個類
import?matplotlib.gridspec?as?gridspec gs?=?gridspec.GridSpec(2,?2)???#?設計一個網格?2行2列 #?選定子繪圖區域 ax1?=?plt.subplot(gs[0,?0]) ax2?=?plt.subplot(gs[0,?1]) ax3?=?plt.subplot(gs[1,?0]) ax4?=?plt.subplot(gs[1,?1])通過使用GridSpec類配合subplot,可以很容易對子區域進行劃定和選擇。
9. 繪制多個子圖
測試數據如下:
代碼如下:
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?matplotlib?as?mpl import?matplotlib.gridspec?as?gridspec import?collections import?numpy?as?np#?讀取數據 df?=?pd.read_csv('soccer.csv',?encoding='gbk')#?子圖1數據 skill_count?=?df['Skill_Moves'].value_counts() skill?=?[f'等級{m}'?for?m?in?skill_count.index]????#?列表推導式構造不同技術等級 counts?=?skill_count.values.tolist()???????????????#?技術等級對應人數統計的列表#?子圖2數據 age_group?=?["17-26",?"27-36",?"37-47"] count_1?=?df[(df['Age']?>=?17)?&?(df['Age']?<=?26)] count_2?=?df[(df['Age']?>=?27)?&?(df['Age']?<=?36)] count_3?=?df[(df['Age']?>=?37)?&?(df['Age']?<=?47)] age_counts?=?[len(count_1),?len(count_2),?len(count_3)]#?子圖3數據 #?&符號?并且????|符號?或???不同條件之間?()括起來 data1?=?df[(17?<=?df['Age'])?&?(df['Age']?<=?26)] age1?=?list(data1['Skill_Moves']) data2?=?df[(27?<=?df['Age'])?&?(df['Age']?<=?36)] age2?=?list(data2['Skill_Moves']) data3?=?df[(37?<=?df['Age'])?&?(df['Age']?<=?47)] age3?=?list(data3['Skill_Moves'])#?分別統計三個年齡段?不同等級人數 count_1?=?collections.Counter(age1).most_common() count_2?=?collections.Counter(age2).most_common() count_3?=?collections.Counter(age3).most_common() count_3.append((5,?0))????#?37-47年齡段等級5人數為零??手動填上 age_counts3?=?count_1?+?count_2?+?count_3datas?=?[[]?for?i?in?range(5)] for?i?in?age_counts3:datas[i[0]-1].append(i[1])grades?=?np.array(datas)#?子圖4數據 skill_moves?=?list(df['Skill_Moves']) skill_count?=?collections.Counter(skill_moves).most_common() skill?=?['等級{}'.format(m[0])?for?m?in?skill_count] counts?=?[n[1]?for?n?in?skill_count]#?繪制多個子圖 mpl.rcParams['font.family']?=?'SimHei' gs?=?gridspec.GridSpec(2,?2) plt.figure(figsize=(12,?20),?dpi=100)ax1?=?plt.subplot(gs[0,?0]) ax2?=?plt.subplot(gs[0,?1]) ax3?=?plt.subplot(gs[1,?0]) ax4?=?plt.subplot(gs[1,?1])ax1.barh(skill[::-1],?counts[::-1],?height=0.5,?color='#FF00FF') ax1.set_xlabel('人數') ax1.set_title('不同技術等級人數統計')ax2.bar(age_group,?age_counts,?width=0.35,?color='red') ax2.set_title('不同年齡段人數統計') ax2.set_xlabel('年齡段') ax2.set_ylabel('人數')ax3.bar(age_group,?grades[0],?label='等級一',?color='red',?width=0.35) ax3.bar(age_group,?grades[1],?bottom=grades[0],?label="等級二",?color="#9400D3",?width=0.35) ax3.bar(age_group,?grades[2],?bottom=grades[0]?+?grades[1],?label="等級三",?color="#0000FF",?width=0.35)??#?轉化為數組??直接相加 ax3.bar(age_group,?grades[3],?bottom=grades[0]?+?grades[1]?+?grades[2],?label="等級四",?color="#FFFF00",?width=0.35) ax3.bar(age_group,?grades[4],?bottom=grades[0]?+?grades[1]?+?grades[2]?+?grades[3],?label="等級五",?color="#006400",?width=0.35) ax3.set_title('不同年齡段等級人數統計') ax3.set_xlabel('年齡段') ax3.set_ylabel('人數')x_?=?[1,?0,?0,?0,?0]???????#?用于顯示空心 color?=?["red",?"blue",?"yellow",?"green",?"purple"] #?正圓 ax4.set_aspect(aspect='equal') ax4.pie(x=counts,?colors=color,?pctdistance=0.9,startangle=45,?autopct='%.1f%%',)ax4.pie(x_,?radius=0.65,?colors="w")???#?小的空白圓填充 ax4.set_title('不同技術等級的運動員人數占比圖') #?調整圖例位置 plt.legend(skill,?bbox_to_anchor=(0.9,?0.92)) plt.show()運行效果如下:
10. matplotlib 繪制熱力圖
Matplotlib 是 Python 著名的 2D 繪圖庫,該庫仿造 Matlab 提供了一整套相似的繪圖函數,用于繪圖和繪表,是強大的數據可視化工具和做圖庫,且繪制出的圖形美觀。
測試數據來源:https://www.tudinet.com/market-0-0-0-0/
代碼如下:
import?pandas?as?pd import?matplotlib.pyplot?as?plt import?numpy?as?np import?matplotlib?as?mpldf?=?pd.read_excel('real_estate_info.xlsx') area?=?df['土地位置']#?成都主要?區?縣?市??9區6縣4市 with?open('test.txt',?encoding='utf-8')?as?f:areas?=?f.read().split('、')for?item?in?areas:#?每個行政區?對每行數據都進行判斷#?土地位置里包含行政區名??值為規劃建筑面積???不包含??值為0#?得到19列?以行政區為列名?其下面值為規劃建筑面積df[item]?=?[eval(df.loc[x,?'規劃建筑面積'][:-1])?if?item?in?df.loc[x,?'土地位置']?else?0?for?x?in?range(len(df['土地位置']))]date?=?df['推出時間'].str.split('年',?expand=True)[0]???#?這列的字符串?按年切割 df['年份']?=?date????????#?添加新的一列??年份df1?=?df[areas] df1.index?=?df['年份'] df2?=?df1.groupby('年份').sum() #?print(df2.iloc[:5,?::])??#?2020年數據只有到2月的??舍去 #?print(type(df2.iloc[:5,?::].T))?????#?轉置 datas?=?np.array(df2.iloc[:5,?::].T)???#?19行?5列?二維數組 print(datas)x_label?=?[year?for?year?in?range(2015,?2020)] y_label?=?areas mpl.rcParams['font.family']?=?'Kaiti'?????#?中文顯示 fig,?ax?=?plt.subplots(figsize=(15,?9))???#?繪圖 heatmap?=?plt.pcolor(datas) for?y?in?range(datas.shape[0]):for?x?in?range(datas.shape[1]):plt.text(x?+?0.5,?y?+?0.5,?'%.1f'?%?datas[y,?x],????#?熱力圖種每個格子添加文本??數據項設置horizontalalignment='center',?verticalalignment='center',)#?x?y軸刻度設置 plt.xticks(np.arange(0.5,?5.5,?1)) plt.yticks(np.arange(0.5,?19.5,?1)) #?x?y軸標簽設置 ax.set_xticklabels(x_label) ax.set_yticklabels(areas) #?title ax.set_title(r'各行政區2015-2019年的總規劃建筑面積(平方米)',?fontsize=25,?x=0.5,?y=1.02)#?隱藏邊框 ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False) ax.spines['bottom'].set_visible(False) plt.savefig('heat_map.png') #?熱力圖???展示 plt.colorbar(heatmap) plt.show()運行效果如下:
matplotlib 繪制 heatmap,該方法比較繁瑣,要調用很多輔助函數才能實現效果更好的熱圖。
其他說明
數據集來源于網絡,僅用于知識交流,真實性未知。
歡迎提出改進意見,以期共同進步,覺得文章還不錯的老鐵點個在看可好呀>_<
文章鏈接:?
1、http://suo.im/5FwbKC?
2、http://suo.im/5NN2UQ?
3、http://suo.im/6alfOZ
公眾號后臺回復:「matplotlib數據可視化」,獲取本文完整數據集。
(防止出錯,建議復制)
總結
以上是生活随笔為你收集整理的看了这个总结,其实 Matplotlib 可视化,也没那么难!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PDF下载!提高代码质量的一本书
- 下一篇: 哎,辣鸡代码书写准则