【Python基礎(chǔ)】手把手教你數(shù)據(jù)可視化!(附實例講解)
點擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)
本文對課程數(shù)據(jù)集及泰坦尼克號數(shù)據(jù)集進(jìn)行了實例講解,一步一步帶你繪制數(shù)據(jù)可視化中常用的五種圖形,并對數(shù)據(jù)間可能存在的相關(guān)性做出了闡述。

常用圖形有:
plt.scatter() 散點圖 plt.plot() ? ?折線圖 plt.bar() 直方圖 plt.pie() 餅圖 plt.boxplot() 箱型圖
#導(dǎo)入相應(yīng)的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
#圖可以顯示中文和負(fù)號
plt.rcParams['font.sans-serif']='SimHei'
plt.rcParams['axes.unicode_minus']=False
data = pd.read_excel("D:\data\student-score\student-score.xlsx")
data.head()

data = data.drop(columns = ["序號","品德","科學(xué)"],axis = 1) #由于品德和科學(xué)的總分與其他學(xué)科不一致,為了圖片顯示效果,刪除這兩個學(xué)科成績
data.loc[:,"總分"] = data.loc[:,"語文"] + data.loc[:,"數(shù)學(xué)"] + data.loc[:,"英語"] #重新計算總分成績
data.head()

接著我們還可以查看其數(shù)據(jù)結(jié)構(gòu):
data.shape #查看數(shù)據(jù)結(jié)構(gòu)
# 輸出
(629, 6)
以及查看各學(xué)科的缺失值情況:
data.isnull().sum() #查看缺失值情況
'''
姓名 0
學(xué)校 0
語文 1
數(shù)學(xué) 0
英語 0
總分 1
dtype: int64
'''
對于這些缺失值,我們可以選擇使用dropna()函數(shù)刪除:
data = data.dropna() #刪除缺失值
data.shape # (628, 6)
再使用describe()函數(shù)進(jìn)行簡單的統(tǒng)計描述:
data.describe() #簡單統(tǒng)計描述

散點圖
gp = data.groupby(by = "學(xué)校",as_index=False) #以學(xué)校為分組依據(jù)進(jìn)行分組
data1=gp.mean() #分組后的聚合運算為計算均值
data1.head()
得到結(jié)果:

# 繪制各學(xué)科成績散點圖
plt.figure(figsize=(6,4))
plt.scatter(data1["總分"],data1["語文"],marker='v')
plt.scatter(data1["總分"],data1["數(shù)學(xué)"],marker='o')
plt.scatter(data1["總分"],data1["英語"],marker='*')
plt.title("各學(xué)校成績散點圖",fontsize = 14)
plt.xlabel("總成績")
plt.ylabel("各學(xué)科成績")
plt.legend(["語文","數(shù)學(xué)","英語"]);

# 繪制各學(xué)科成績散點圖
plt.figure(figsize=(6,4))
plt.scatter(data1["總分"],data1["語文"],marker='v')
plt.title("各學(xué)校語文與總分成績散點圖",fontsize = 14)
plt.xlabel("總成績")
plt.ylabel("各學(xué)科成績")
plt.legend(["語文"])
#

# 繪制各學(xué)科成績散點圖
data1.plot.scatter(x = "總分", y = "語文")
plt.title("語文與總分成績散點圖")
data1.plot.scatter(x = "總分", y = "數(shù)學(xué)")
plt.title("數(shù)學(xué)與總分成績散點圖")
data1.plot.scatter(x = "總分", y = "英語")
plt.title("英語與總分成績散點圖")
# plt.show()
得到Text(0.5, 1.0, '英語與總分成績散點圖'),且散點圖結(jié)果如下:



折線圖
data1.head()

data1["序號"]=data1.學(xué)校.str.extract('(\d+)')
data1


ser1 = data1.序號
ser1
得到輸出:
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
10 1
11 20
12 21
13 2
14 3
15 4
16 5
17 6
18 7
19 8
20 9
Name: 序號, dtype: object
接著:
ser1 = ser1.astype("int")
ser1
得到輸出:
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
10 1
11 20
12 21
13 2
14 3
15 4
16 5
17 6
18 7
19 8
20 9
Name: 序號, dtype: int32
可以嘗試刪除序號列,并且重設(shè)索引列:
del data1["序號"]
data1.index = ser1
data1


再按照索引排序,可得到相應(yīng)結(jié)果:
data1=data1.sort_index()
data1


接著查看一共有多少行數(shù)據(jù)作為x軸數(shù)據(jù)
len(data1) # 21
再將各科成績數(shù)據(jù)進(jìn)行繪圖,得到折線圖結(jié)果:
plt.figure(figsize=(10,4))
plt.plot(range(21),data1.iloc[:,1],'-*') #選取語文成績數(shù)據(jù)
plt.plot(range(21),data1.iloc[:,2],'-o') #選取數(shù)學(xué)成績數(shù)據(jù)
plt.plot(range(21),data1.iloc[:,3],'-v') #選取英語成績數(shù)據(jù)
plt.title('各學(xué)科成績變化走勢圖')
plt.xlabel('各學(xué)校')
plt.ylabel('學(xué)科成績')
plt.xticks(range(21),data1["學(xué)校"],rotation=30) #rotation=30控制文字傾斜角度
plt.legend(['語文','數(shù)學(xué)','英語']);

直方圖
yw = data1.loc[:,"學(xué)校":"語文"] #提取數(shù)據(jù)繪制直方圖,直方圖原理,每個需要被畫圖的標(biāo)簽對應(yīng)一個數(shù)值
yw = yw.T
yw

yw.columns = yw.iloc[0] #將學(xué)校字段轉(zhuǎn)換成列索引
yw1 = yw.drop("學(xué)校",axis=0) #刪多余的行信息
yw1

再將語文成績數(shù)據(jù)進(jìn)行繪圖,得到直方圖結(jié)果:
# 每個學(xué)校語文平均成績的直方圖
plt.figure(figsize=(12,4))
plt.bar(range(21),yw.loc["語文",:],width=0.5)
plt.title("語文成績直方圖",fontsize = 14)
plt.ylabel("語文成績",fontsize = 14)
plt.xticks(range(21),yw.iloc[0],rotation=30,fontsize = 12); #x軸刻度為各學(xué)校名稱

sx = data1.loc[:,["學(xué)校","數(shù)學(xué)"]]
sx = sx.T
sx

sx.columns = sx.iloc[0]
sx = sx.drop("學(xué)校",axis=0)
sx

再將數(shù)學(xué)平均成績數(shù)據(jù)進(jìn)行繪圖,得到直方圖結(jié)果:
# 每個學(xué)校數(shù)學(xué)平均成績的直方圖
plt.figure(figsize=(12,4))
plt.bar(range(21),sx.loc["數(shù)學(xué)",:],width=0.5)
plt.title("數(shù)學(xué)成績直方圖",fontsize = 14)
plt.ylabel("數(shù)學(xué)成績",fontsize = 14)
plt.xticks(range(21),yw.iloc[0],rotation=30,fontsize = 12); #x軸刻度為各學(xué)校名稱

將多個學(xué)科成績畫到一副圖中
data1


data2 = data1.drop("總分",axis = 1) #新建一個dataframe,刪掉總分列,因為總分和單科成績相差太多,影響繪圖效果
data2.head()

# 將多個學(xué)科成績畫到一張圖中 #截取前十
data2.plot.bar(x = '學(xué)校',y = ['語文','數(shù)學(xué)','英語'],figsize=(16,6),width=0.7,rot = 30,title = "各學(xué)科成績直方圖"); #rot空值標(biāo)簽傾斜程度

餅圖
data2.head()

plt.figure(figsize=(4,4),dpi=80)
plt.pie(data2.iloc[0,1:] #選取數(shù)據(jù)源
,labels=['語文','數(shù)學(xué)','英語']
,autopct='%1.2f') #設(shè)置百分比經(jīng)度
# ,explode=[0.1,0.02,0.02] #設(shè)置餅圖各個扇區(qū)之間的間隙
# ,colors=['r','g','b']) #設(shè)置餅圖各個扇區(qū)的顏色
plt.title('第1小學(xué)各學(xué)科成績占比',fontsize=12);
#fontsize設(shè)定字體的大小,xlabel,ylabel,title里面都可以設(shè)定

pic2 = plt.figure(figsize=(8,8),dpi=80)
fig1 = pic2.add_subplot(2,2,1) #第一個子圖
plt.pie(data2.iloc[0,1:] #選取數(shù)據(jù)源 第10小學(xué)各學(xué)科成績
,labels=['語文','數(shù)學(xué)','英語']
,autopct='%1.2f') #設(shè)置百分比經(jīng)度
# ,explode=[0.1,0.02,0.02] #設(shè)置餅圖各個扇區(qū)之間的間隙
# ,colors=['r','g','b']) #設(shè)置餅圖各個扇區(qū)的顏色
plt.title('第1小學(xué)各學(xué)科成績占比',fontsize=12)
fig2 = pic2.add_subplot(2,2,2) #第二個字圖
plt.pie(data2.iloc[1,1:] #選取數(shù)據(jù)源,第11小學(xué)各學(xué)科成績
,labels=['語文','數(shù)學(xué)','英語']
,autopct='%1.2f') #設(shè)置百分比經(jīng)度
# ,explode=[0.1,0.02,0.02] #設(shè)置餅圖各個扇區(qū)之間的間隙
# ,colors=['r','g','b']) #設(shè)置餅圖各個扇區(qū)的顏色
plt.title('第2小學(xué)各學(xué)科成績占比',fontsize=12)
fig3 = pic2.add_subplot(2,2,3) #第二個字圖
plt.pie(data2.iloc[2,1:] #選取數(shù)據(jù)源,第12小學(xué)各學(xué)科成績
,labels=['語文','數(shù)學(xué)','英語']
,autopct='%1.2f') #設(shè)置百分比經(jīng)度
# ,explode=[0.1,0.02,0.02] #設(shè)置餅圖各個扇區(qū)之間的間隙
# ,colors=['r','g','b']) #設(shè)置餅圖各個扇區(qū)的顏色
plt.title('第3小學(xué)各學(xué)科成績占比',fontsize=12)
fig4 = pic2.add_subplot(2,2,4) #第二個字圖
plt.pie(data2.iloc[3,1:] #選取數(shù)據(jù)源,第13小學(xué)各學(xué)科成績
,labels=['語文','數(shù)學(xué)','英語']
,autopct='%1.2f') #設(shè)置百分比經(jīng)度
# ,explode=[0.1,0.02,0.02] #設(shè)置餅圖各個扇區(qū)之間的間隙
# ,colors=['r','g','b']) #設(shè)置餅圖各個扇區(qū)的顏色
plt.title('第4小學(xué)各學(xué)科成績占比',fontsize=12);

箱型圖
data.head()

data_1 = data.loc[data['學(xué)校'] =="第1小學(xué)"] #提取第一小學(xué)的所有信息
score = (list(data_1.iloc[:,2]),list(data_1.iloc[:,3]),list(data_1.iloc[:,4]))
plt.figure(figsize=(8,6))
plt.boxplot(score
,labels=['語文','數(shù)學(xué)','英語']
,notch=True #缺口中位數(shù)位置
,sym='*'#設(shè)定異常值的形狀
,whis=1.5); #設(shè)定幾倍標(biāo)準(zhǔn)差之外的數(shù)據(jù)算是異常值,默認(rèn)是1.5

text = pd.read_csv(r'result.csv')
text.head()

男女中生存人數(shù)分布情況
sex = text.groupby('Sex')['Survived'].sum()
sex.plot.bar(color='chocolate')
plt.title('survived_count')
plt.show()

女性比男性生存人數(shù)多。
男女中生存人與死亡人數(shù)的比例
text.groupby(['Sex','Survived'])['Survived'].count().unstack().plot(kind='bar',stacked='True')
plt.title('survived_count')
plt.ylabel('count')
# Text(0, 0.5, 'count')

男女性生存與死亡人數(shù)的占比偏差比較大。
不同票價的人生存和死亡人數(shù)分布情況
# 排序后繪折線圖
fare_sur = text.groupby(['Fare'])['Survived'].value_counts().sort_values(ascending=False)
fig = plt.figure(figsize=(20, 18))
fare_sur.plot(grid=True)
plt.legend()
plt.show()

不同的票價所反映出來的生存人數(shù)是非常明顯的,票價低的人死亡數(shù)量高是因為離甲板遠(yuǎn),且逃生機會大大降低。
# 排序前繪折線圖
fare_sur1 = text.groupby(['Fare'])['Survived'].value_counts()
fig = plt.figure(figsize=(20, 18))
fare_sur1.plot(grid=True)
plt.legend()
plt.show()

不同倉位等級的人生存和死亡人員的分布情況
# 1表示生存,0表示死亡
pclass_sur = text.groupby(['Pclass'])['Survived'].value_counts()
import seaborn as sns
sns.countplot(x="Pclass", hue="Survived", data=text)
#
不同年齡的人生存與死亡人數(shù)分布情況facet = sns.FacetGrid(text, hue="Survived",aspect=3)
facet.map(sns.kdeplot,'Age',shade= True)
facet.set(xlim=(0, text['Age'].max()))
facet.add_legend()
#
不同倉位等級的人年齡分布情況text.Age[text.Pclass == 1].plot(kind='kde')
text.Age[text.Pclass == 2].plot(kind='kde')
text.Age[text.Pclass == 3].plot(kind='kde')
plt.xlabel("age")
plt.legend((1,2,3),loc="best")
#

交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~
