數(shù)據(jù)可視化就是使用圖形圖表等方式來呈現(xiàn)數(shù)據(jù),圖形圖表能夠高效清晰地表達數(shù)據(jù)包含的信息连躏。數(shù)據(jù)可視化在各個領域都得到了廣泛的應用剩岳,例如,產(chǎn)品銷售數(shù)據(jù)的可視化入热,統(tǒng)計樣本數(shù)據(jù)可視化拍棕,機器學習數(shù)據(jù)可視化等。
Python有很多非常優(yōu)秀易用的數(shù)據(jù)可視化的庫勺良,其中最著名的要數(shù)matplotlib了绰播,它有著十幾年的歷史,至今仍然是Python使用者最常用的畫圖庫尚困。
Seaborn跟matplotlib最大的區(qū)別就是它的默認繪圖風格和色彩搭配都具有現(xiàn)代美感蠢箩,其實是在matplotlib的基礎上進行了更高級的API封裝,讓你能用更少的代碼去調用 matplotlib的方法,從而使得作圖更加容易谬泌,在大多數(shù)情況下使用seaborn就能做出很具有吸引力的圖滔韵,而使用matplotlib就能制作具有更多特色的圖。應該把Seaborn視為matplotlib的補充掌实,而不是替代物陪蜻。
安裝
pip install matplotlib
pip install seaborn
參數(shù)配置
matplotlib.pyplot使用rc配置文件來自定義圖形的各種默認屬性,稱之為rc配置或rc參數(shù)潮峦。通過rc參數(shù)可以修改默認的屬性囱皿,包括窗體大小勇婴、每英寸的點數(shù)忱嘹、線條寬度拘悦、顏色础米、樣式、坐標軸添诉、坐標和網(wǎng)絡屬性屁桑、文本、字體等栏赴。
經(jīng)過優(yōu)化配置后圖表會更美觀蘑斧。
#-*- coding:utf-8 -*-
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
# 一些默認配置,使得圖表更美觀
large = 22; med = 16; small = 12
params = {'axes.titlesize': large,
'legend.fontsize': med,
'figure.figsize': (16, 10),
'axes.labelsize': med,
'axes.titlesize': med,
'xtick.labelsize': med,
'ytick.labelsize': med,
'figure.titlesize': large}
plt.rcParams.update(params)
plt.style.use('seaborn-whitegrid')
sns.set_style("white")
# 設置matplotlib正常顯示中文
plt.rcParams['font.sans-serif']=['SimHei'] # 用黑體顯示中文
plt.rcParams['axes.unicode_minus']=False
1须眷、直方圖
直方圖(Histogram)竖瘾,又稱質量分布圖,是一種統(tǒng)計報告圖花颗,由一系列高度不等的縱向條紋或線段表示數(shù)據(jù)分布的情況捕传。 一般用橫軸表示數(shù)據(jù)類型,縱軸表示分布情況扩劝。
def plot_dist(title, x):
'''
繪制質量分布圖
INPUT -> 標題, 數(shù)據(jù)集(單變量)
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.distplot(x, hist=True, kde=True, rug=True) # 前兩個代表直方圖和一元核密度估計圖,默認就是True;rug是在最下方顯示出頻率情況,默認為False
plt.title(title, fontsize=22)
plt.show()
# 生成一些隨機數(shù)
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
plot_dist('測試圖', s)
2庸论、核密度估計圖
核密度估計(kernel density estimation)是在概率論中用來估計未知的密度函數(shù),屬于非參數(shù)檢驗方法之一棒呛。通過核密度估計圖可以比較直觀的看出數(shù)據(jù)樣本本身的分布特征聂示。
def plot_1kde(title, x, cumulative=False):
'''
繪制一元核密度估計圖
INPUT -> 標題, 數(shù)據(jù)集(單變量)
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.kdeplot(x, cumulative=cumulative, shade=True, color='r') # cumulative為密度累計, shade表示線下顏色為陰影, color表示顏色是紅色
plt.title(title, fontsize=22)
plt.show()
def plot_2kde(title, x, y):
'''
繪制二元核密度估計圖
INPUT -> 標題, 字段1, 字段2
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.kdeplot(x, y, shade=True, cbar=True) # cbar表示顏色棒
plt.title(title, fontsize=22)
plt.show()
# 生成一些隨機數(shù)
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
h = pd.Series(rs.randn(70) * 100)
plot_1kde('測試圖', s)
plot_2kde('測試圖2', s, h)
3催什、散點圖
def plot_joingrid(x, y):
'''
繪制兩個變量關系圖
INPUT -> 字段1, 字段2
'''
g = sns.jointplot(x=x, y=y, # 設置xy軸气筋,顯示columns名稱
color = 'k', # 設置顏色
s = 50, edgecolor="w",linewidth=1, # 設置散點大小、邊緣線顏色及寬度(只針對scatter)
kind = 'scatter', # 設置類型:“scatter”搀矫、“reg”、“resid”鲁森、“kde”、“hex”
space = 0.2, # 設置散點圖和布局圖的間距
size = 5, # 圖表大心馍蕖(自動調整為正方形)
ratio = 4, # 散點圖與布局圖高度比,整型
marginal_kws=dict(bins=15, rug=True) # 設置柱狀圖箱數(shù)欢搜,是否設置rug
)
g = g.set_axis_labels("X","Y")
plt.show()
# 生成一些隨機數(shù)
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
h = pd.Series(rs.randn(70) * 100)
plot_joingrid(s, h)
4、分類/分簇散點圖
Stripplot按照不同類別對樣本數(shù)據(jù)進行分布散點圖繪制。
Swarmplot也是繪制散點圖廓推,但它會通過算法,在類別坐標軸的方向上延展那些原本重合的點专缠,與通過Stripplot.jitter屬性增加抖動有異曲同工之妙哥力。
def plot_pairgrid1(x, y):
'''
繪制分類散點圖
INPUT -> 分組列, 統(tǒng)計列
'''
colors = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
sns.stripplot(x=x, # 設置分組統(tǒng)計字段
y=y, # 數(shù)據(jù)分布統(tǒng)計字段
# 這里xy數(shù)據(jù)對調渔工,會使得散點圖橫向分布
jitter=0.05, # jitter代表設置抖動
edgecolor = 'w', linewidth = 1, marker = 'o',
palette=colors)
plt.show()
def plot_pairgrid2(x, y):
'''
繪制分簇散點圖
INPUT -> 分組列, 統(tǒng)計列
'''
colors = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
sns.swarmplot(x=x, # 設置分組統(tǒng)計字段
y=y, # 數(shù)據(jù)分布統(tǒng)計字段
# 這里xy數(shù)據(jù)對調轧粟,會使得散點圖橫向分布
edgecolor = 'w', linewidth = 1, marker = 'o',
palette=colors)
plt.show()
tips = sns.load_dataset('tips')
plot_pairgrid1(tips['day'], tips['total_bill'])
plot_pairgrid2(tips['day'], tips['total_bill'])
5、箱體圖/小提琴圖/LV圖
通過Boxplot可以看到數(shù)據(jù)的最大值珊燎、上四分位數(shù)Q3延旧、中位數(shù)芦瘾、下四分位數(shù)Q1近弟、最小值和異常值的分布。
Violinplot與Boxplot相似迫摔,但其圖形如同小提琴般句占,可以更好地展現(xiàn)出數(shù)據(jù)的量化形態(tài)。
lvplot(信值圖)是箱線圖和提琴圖的混合,但是對于大數(shù)據(jù)集有更強的縮放能力哺壶,渲染速度更快。
def plot_box(x, y):
'''
繪制箱體圖
INPUT -> 字段1, 字段2
'''
sns.boxplot(x = x, y = y,
# data = df,
linewidth = 2, #線寬
width = 0.8, # 箱之間的間隔比例
fliersize = 3, #異常點大小
whis = 1.5, #設置IQR
notch = True, #設置是否以中值做凹槽
order = {'Thur','Fri','Sat','Sun'}, # 篩選類別
palette='Set2' #設置調色板
)
#可以添加散點圖
sns.swarmplot(x = x, y = y, color = 'k', size = 3, alpha = 0.8)
plt.show()
def plot_violin(x, y):
'''
繪制小提琴圖
INPUT -> 字段1, 字段2
'''
sns.violinplot(x = x, y = y,
# data = df,
linewidth = 2, # 線寬
width = 0.8, # 箱之間的間隔比例
fliersize = 3, # 異常點大小
whis = 1.5, # 設置IQR
notch = True, # 設置是否以中值做凹槽
scale = 'count', # 測度小提琴圖的寬度: area-面積相同,count-按照樣本數(shù)量決定寬度,width-寬度一樣
order = {'Thur','Fri','Sat','Sun'}, # 篩選類別
palette='Set2', #設置調色板
# hue = z, # 按z再細分
# split = True, # 設置是否按z拆分小提琴圖
)
plt.show()
def plot_lv(x, y):
'''
繪制LV圖(信值圖)
INPUT -> 字段1, 字段2
'''
sns.lvplot(x = x, y = y,
# data = df,
palette = 'mako',
linewidth = 12, # 線寬
width = 0.8, # 箱之間的間隔比例
scale = 'area', # 設置框的大小:'linear'绷杜、'exonential'、'area'
k_depth = 'proportion' # 設置框的數(shù)量:'proportion','tukey','trustworthy'
)
plt.show()
tips = sns.load_dataset('tips')
plot_box(tips['day'], tips['total_bill'])
plot_violin(tips['day'], tips['total_bill'])
plot_lv(tips['day'], tips['total_bill'])
6鹃两、矩陣圖
矩陣圖可以用于繪制展現(xiàn)數(shù)據(jù)集內多個變量之間兩兩關系。
def plot_pairgrid(df, mark=None):
'''
繪制矩陣圖
INPUT -> 數(shù)據(jù)集, 分類標簽
'''
g = sns.PairGrid(data=df,
hue=mark)
# vars=["sepal_width", "sepal_length"] vars:需要組合的數(shù)據(jù)字段
g = g.map_diag(sns.kdeplot, lw=3, legend=False) # 單變量
# g = g.map_offdiag(plt.scatter)
g = g.map_upper(plt.scatter)
g = g.map_lower(sns.kdeplot, cmap="Blues_d")
for ax in g.axes.flat:
plt.setp(ax.get_xticklabels(), rotation=45)
plt.show()
7、熱力圖
seaborn中的熱力圖宽堆,有利于數(shù)據(jù)特征的關聯(lián)性表示
def plot_heatmap(title, df):
'''
繪制熱力圖
INPUT -> 標題, 數(shù)據(jù)集
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.heatmap(df.corr(), xticklabels=df.corr().columns, yticklabels=df.corr().columns, cmap='RdYlGn', center=0, annot=True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.title(title, fontsize=22)
plt.show()
6号胚、時序圖
def plot_timeseries(x, y, title, df):
'''
繪制時序圖
INPUT -> 時間字段, 數(shù)量字段, 標題, 數(shù)據(jù)集
'''
plt.figure(figsize=(16,10), dpi= 80)
plt.plot(x, y, data=df, color='tab:red')
plt.ylim(0, 1000) # y軸顯示范圍
xtick_location = df.index.tolist()[::12] # x軸取最近12個
xtick_labels = [i[-4:] for i in df.date.tolist()[::12]] # 年份
plt.xticks(ticks=xtick_location, labels=xtick_labels, rotation=0, fontsize=12, horizontalalignment='center', alpha=.7)
plt.yticks(fontsize=12, alpha=.7)
plt.title(title, fontsize=22)
plt.grid(axis='both', alpha=.3)
# 移除邊框
plt.gca().spines["top"].set_alpha(0.0)
plt.gca().spines["bottom"].set_alpha(0.3)
plt.gca().spines["right"].set_alpha(0.0)
plt.gca().spines["left"].set_alpha(0.3)
plt.show()