箱線圖boxplot


箱線圖boxplot——展示數據的分布


圖表作用:

1.反映一組數據的分布特征,如:分布是否對稱,是否存在離群點

2.對多組數據的分布特征進行比較

3.如果只有一個定量變量,很少用箱線圖去看數據的分布,而是用直方圖去觀察。一般都要跟其余的定性變量做分組箱線圖,可以起對比作用。(key)

適合數據類型:

針對連續型變量

用法:

只有一個變量、一組的數據(1個變量,0個定性變量),比如:學生的成績情況

只有一個變量、多組數據(1個變量,1個定性變量[班級]),比如:1、2、3班學生的成績情況

只有一個變量、多組數據(1個變量,多個定性變量[年級、班級]),比如:初一、初二、初三的1、2、3班學生的成績情況

多個變量同理,看Y軸數據大小才相近才采用此用法

圖表解讀:

1.箱子的大小取決於數據的四分位距,即IQR = Q3 - Q1(Q3: 75%分位數 , Q1: 25%分位數 , Q3和Q1為四分位數)。50%的數據集中於箱體,若箱體太大即數據分布離散,數據波動較大,箱體小表示數據集中。

2.箱子的上邊為上四分位數Q3,下邊為下四分位數Q1,箱體中的橫線為中位數Q2(50%分位數)

3.箱子的上觸須為數據的最大值Max,下觸須為數據的最小值Min(注意是非離群點的最大最小值,稱為上下相鄰值)

4.若數據值 > Q3+1.5 * IQR(上限值) 或 數據值 < Q1-1.5 * IQR(下限值) ,均視為異常值。數據值 > Q3+3 * IQR 或 數據值 < Q1-3 * IQR ,均視為極值。在實際應用中,不會顯示異常值與極值的界限,而且一般統稱為異常值。

  • 也表明上下觸須不一定是數據的最大最小值,
  • (1)若數據的最大值比上限值小的,那么上觸須頂點就是觀察到的最大的;若數據的最大值比上限值大的,那么上觸須頂點就是上限值,觀察到的最大值就是異常點。
  • (2)若數據的最小值比下限值大的,那么下觸須頂點就是觀察到的最小值;若數據的最小值比下限值小的,那么下觸須頂點就是下限值,觀察到的最小值就是異常點。
  • 上述情況復雜,在線范圍外的,直接理解成異常值即可

5.偏度:

  • 對稱分布:中位線在箱子中間,上下相鄰值到箱子的距離等長,離群點在上下限值外的分布也大致相同。
  • 右偏分布:中位數更靠近下四分位數,上相鄰值到箱子的距離比下相鄰值到箱子的距離長,離群點多數在上限值之外。
  • 左偏分布:中位數更靠近上四分位數,下相鄰值到箱子的距離比上相鄰值到箱子的距離長,離群點多數在下限值之外。

作圖實操:

下面是plt.boxplot()的參數

plt.boxplot(x,
notch=None,
sym=None,
vert=None,
whis=None,
positions=None,
widths=None,
patch_artist=None,
bootstrap=None,
usermedians=None,
conf_intervals=None,
meanline=None,
showmeans=None,
showcaps=None,
showbox=None,
showfliers=None,
boxprops=None,
labels=None,
flierprops=None,
medianprops=None,
meanprops=None,
capprops=None,
whiskerprops=None,
manage_xticks=True,
autorange=False,
zorder=None,
hold=None,
data=None)

  • x:指定要繪制箱線圖的數據;
  • notch:是否是凹口的形式展現箱線圖,默認非凹口;
  • sym:指定異常點的形狀,默認為+號顯示;
  • vert:是否需要將箱線圖垂直擺放,默認垂直擺放;
  • whis:指定上下須與上下四分位的距離,默認為1.5倍的四分位差;
  • positions:指定箱線圖的位置,默認為[0,1,2…];
  • widths:指定箱線圖的寬度,默認為0.5;
  • patch_artist:是否填充箱體的顏色;
  • meanline:是否用線的形式表示均值,默認用點來表示;
  • showmeans:是否顯示均值,默認不顯示;
  • showcaps:是否顯示箱線圖頂端和末端的兩條線,默認顯示;
  • showbox:是否顯示箱線圖的箱體,默認顯示;
  • showfliers:是否顯示異常值,默認顯示;
  • boxprops:設置箱體的屬性,如邊框色,填充色等;
  • labels:為箱線圖添加標簽,類似於圖例的作用;
  • filerprops:設置異常值的屬性,如異常點的形狀、大小、填充色等;
  • medianprops:設置中位數的屬性,如線的類型、粗細等;
  • meanprops:設置均值的屬性,如點的大小、顏色等;
  • capprops:設置箱線圖頂端和末端線條的屬性,如顏色、粗細等;
  • whiskerprops:設置須的屬性,如顏色、粗細、線的類型等;

例1

import numpy as np
import matplotlib.pyplot as plt
plt.style.use("ggplot")
plt.rcParams["font.sans-serif"]=["SimHei"] #正常顯示中文標簽
plt.rcParams["axes.unicode_minus"]=False   #正常顯示負號
np.random.seed(800)   #設置隨機種子
data=np.random.randint(1,100,55)
plt.figure(figsize=(5,6))    #設置圖形尺寸大小
plt.boxplot(data,
            notch=False,  #中位線處不設置凹陷
            widths=0.2,   #設置箱體寬度
            medianprops={'color':'red'},  #中位線設置為紅色
            boxprops=dict(color="blue"),  #箱體邊框設置為藍色
            labels="A",  #設置標簽
            whiskerprops = {'color': "black"}, #設置須的顏色,黑色
            capprops = {'color': "green"},      #設置箱線圖頂端和末端橫線的屬性,顏色為綠色
            flierprops={'color':'purple','markeredgecolor':"purple"} #異常值屬性,這里沒有異常值,所以沒表現出來
           )
plt.title("55個1-100的隨機整數的箱線圖",fontsize="xx-large",color="#DE0052")
plt.show()

例2

拿Titanic數據,作乘客年齡的箱線圖

import pandas as pd
import matplotlib.pyplot as plt 
train = pd.read_csv(r"G:\Kaggle\Titanic\train.csv")
any(train.Age.isnull()) #檢查年齡是否有缺失
train.dropna(subset=["Age"], inplace=True)  #刪除含有缺失年齡的觀測,即行
plt.style.use("ggplot")  #使用ggplot的圖形style
plt.rcParams["font.sans-serif"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False   # 設置中文、負號正常顯示
plt.figure(figsize=(5,6))
plt.boxplot(x = train.Age,     # 繪圖數據 
            notch = True,      #設置中位線處凹陷,(注意:下圖看起來有點丑)
            patch_artist=True, # 設置用自定義顏色填充盒形圖,默認白色填充 
            showmeans=True,    # 以點的形式顯示均值 
            boxprops = {"color":"black","facecolor":"#F43D68"}, # 設置箱體屬性,填充色and 邊框色 
            flierprops = {"marker":"o","markerfacecolor":"#59EA3A","color":"#59EA3A"}, # 設置異常值屬性,點的形狀、填充色和邊框色 
            meanprops = {"marker":"D","markerfacecolor":"white"}, # 設置均值點的屬性,點的形狀、填充色 
            medianprops = {"linestyle":"--","color":"#FBFE00"}         # 設置中位數線的屬性,線的類型和顏色
            ) 
plt.ylim(0,85)  # 設置y軸的取值范圍
plt.title("乘客年齡箱線圖",fontsize="xx-large",color="#DE0052")
plt.tick_params(top="off", right="off")  # 去掉o箱線圖的上方及右方邊框的刻度標簽
plt.show()   # 顯示圖形,jupyter notebook有另一種寫法,可以不用每一次畫圖都碼這句

乘客的平均年齡為30歲,有50%的人,年齡落在20~38歲之間(看箱體);中位線偏下,上相鄰值到箱子的距離比下相鄰值到箱子的距離長,異常值多在上限值之外,說明年齡整體右偏;有偏大的異常值在64歲以上。

例3 針對箱線圖箱體太扁、異常值突出情況

借用kaggle泰坦尼克號生存預測數據:Fare一項作為例子

import pandas as pd
import numpy as np
df = pd.read_csv(r"G:\Kaggle\Titanic\train.csv") 
plt.figure(figsize=(5,6))
plt.boxplot("Fare",data=df)
plt.title("乘客船票價格箱線圖",fontsize="xx-large",color="#DE0052")
plt.show()

箱體很扁,異常值特別突出,難以看出數據的分布情況。留意到票價均為正數,我們選擇將票價做對數變換。否則就換另一種圖形來呈現數據,箱線圖不行。

換seaborn來畫

import seaborn as sns
plt.figure(figsize=(5,6))
sns.boxplot(y="Fare",data=df)    #不注明y軸的話,箱線圖是橫躺着的
plt.title("乘客船票價格箱線圖2",fontsize="xx-large",color="#DE0052")
plt.show()#DE0052

下面做對數變換,然后再畫箱線圖:

x = df.Fare
df["new_Fare"] = np.log(x)
plt.figure(figsize=(5,6))
plt.boxplot(x="new_Fare",data=df)
plt.title("乘客船票價格箱線圖(對數變換后)",fontsize="xx-large",color="#DE0052")
plt.show()
F:\Anaconda\lib\site-packages\ipykernel_launcher.py:2: RuntimeWarning: divide by zero encountered in log

這樣就好看多了,看得出中位線、數據分布情況,異常值也沒這么凸顯了。

用seaborn來畫

plt.figure(figsize=(5,6))
sns.boxplot(y="new_Fare",data=df,width=0.2)  #不注明y軸的話,箱線圖是橫躺着的
plt.title("乘客船票價格箱線圖2(對數變換后)",fontsize="xx-large",color="#DE0052")
plt.show()

看出船票票價整體右偏,存在偏高的異常值。

例4

在一個定量變量的基礎上,加入Pclass定性變量進行分組

plt.figure(figsize=(5,6))
sns.boxplot(x="Pclass",y="new_Fare",data=df,width=0.35)
plt.title("不同船艙等級乘客船票價格箱線圖(對數變換后)",fontsize="xx-large",color="#DE0052")
plt.show()

對數變換后,不同船艙等級乘客的票價都呈現右偏,票價中位數:一等艙 > 二等艙 > 三等艙,一等艙的票價普遍比二、三等艙的票價高。同時看到,一等艙存在個別票價偏低、偏高的乘客,三等艙存在部分乘客票價異常情況。

在一個定量變量、一個定性變量的基礎上,再加入一個定性變量Survived進行分組

plt.figure(figsize=(6,6))
sns.boxplot(x="Pclass",y="new_Fare",hue="Survived",data=df,width=0.6)
plt.title("不同船艙等級乘客船票價格箱線圖2(對數變換后)",fontsize="xx-large",color="#DE0052")
plt.show()

  • 隨着船艙等級的升高,船票價格也是隨之升高的;
  • 而且在同一船艙等級中,存活下來的乘客的票價中位數均比死亡乘客的票價中位數高;
  • 在一等艙中,死亡乘客中存在一個票價異常低的乘客,而存活下來的乘客中存在一個票價異常高的乘客;
  • 在三等艙中,死亡乘客中存在票價異常高的乘客,生存乘客中也存在一個票價異常高的乘客。與一等艙形成對比。

今天先作此筆記,plt.boxplot()的加入類別型變量、整塊圖形的背景色、坐標軸的字體大小還未解決。后期補上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM