python科學計算——資料視覺化(2) Seaborn
寫在前面
在前面的文章介紹了Matplotlib的視覺化基本功能,seaborn是基於Matplotlib的基礎上進行了封裝,能夠快速的繪製精美的圖表,使用起來比matplotlib更為方便簡潔,本文是參考seaborn的官方文件進行的總結。
seaborn的樣式控制
先看一下利用Matplotlib的繪製圖像:
def sinp(flip=1):
x = np.linspace(0,14,100)
for i in range(1,7):
plt.plot(x, np.sin(x+i*.5)*(7-i)*flip)
sinp()
plt.show()
上面是用Matplotlib預設樣式來進行繪圖的,要變成seaborn的預設樣式,簡單的呼叫sns.set()就可以了:
sns.set()
sinp()
上圖是用seaborn的預設樣式的繪製結果,兩圖之間還是由比較大的差別,可以想象到,sns.set()是呼叫了matplotlib中的函式進行了設定。seaborn的控制引數包括兩部分,figure樣式的控制是用set_style()和axes_style(),而控制圖表的plotting_context() 和set_context()。
Figure樣式控制
seaborn預先定義了5中主題樣式,以適合不同場景需要,分別是:darkgrid, whitegrid, dark, white, 和ticks,預設是darkgrid。
sns .set_style("whitegrid")
data = np.random.normal(size=(20, 6)) + np.arange(6) / 2
sns.boxplot(data=data)
sns.set_style("dark")
sinp()
sns.set_style("white")
sinp()
# 刻度樣式
sns.set_style("ticks")
sinplot()
# 移除軸
sinplot()
sns.despine()
f, ax = plt.subplots()
sns.violinplot(data=data)
# trim是左下角不連線,offset
sns.despine(offset=10,trim=True)
plt.show()
圖樣式
seaborn預定義了4種圖表的樣式定義,分別是:paper、notebook、talk和poster,預設是notebook,分別看看效果:
sns.set_context("paper")
sinp()
sns.set_context("talk")
sinp()
sns.set_context("poster")
sinp()
除此之外,還可以為set_context()提供其他引數來控制樣式。
sns.set_context("notebook", font_scale=1.5, rc={"lines.linewidth": 2.5})
sinp()
調色盤
seaborn中的調色盤使用函式color_palette(),該函式接受seaborn或者matplotlib(除了jet)的colormap物件,或者接受RGB、十六進位制的顏色表示以及HTML的顏色名,如果不使用任何引數呼叫color_palette()則返回當前調色盤,set_palette()函式則將傳入的調色盤選擇為當前調色盤。
定性調色盤
定性調色盤(Qualitative color palettes)適合於區分沒有固定順序的離散資料。
# 獲取seaborn的預設調色盤
current_palette = sns.color_palette()
sns.palplot(current_palette)
預設的seaborn調色盤只有6中顏色,如果需要增加更多的顏色,最簡單的方式是hls顏色空間:
sns.palplot(sns.color_palette("hls", 10))
同時可以使用引數來調整顏色的飽和度和亮度:
通過傳入顏色來建立調色盤:
flatui = ["#9b59b6", "#3498db", "#95a5a6", "#e74c3c", "#34495e", "#2ecc71"]
sns.palplot(sns.color_palette(flatui))
使用顏色名稱來建立調色盤:
colors = ["windows blue", "amber", "greyish", "faded green", "dusty purple"]
sns.palplot(sns.xkcd_palette(colors))
所有的顏色名參見這裡,此外,seaborn提供了一個xkcd_rgb可以快速使用這些顏色名:
plt.plot([0, 1], [0, 1], sns.xkcd_rgb["pale red"], lw=3)
plt.plot([0, 1], [0, 2], sns.xkcd_rgb["medium green"], lw=3)
plt.plot([0, 1], [0, 3], sns.xkcd_rgb["denim blue"], lw=3)
漸變色
sns.palplot(sns.color_palette("Blues"))
如果要反序這些漸變色,則在顏色後面加_r:
sns.palplot(sns.color_palette("Blues_r"))
cubehelix調色盤:
sns.palplot(sns.color_palette("cubehelix", 8))
sns.palplot(sns.color_palette("BrBG", 7))
更加複雜的調色盤參看這裡
繪圖函式
分佈圖
distplot()是繪製單變數的資料分佈圖:
x = np.random.normal(size=100)
sns.distplot(x)
該函式同樣可以實現直方圖的繪製,其中的rug引數可以控制顯示資料在軸上的位置:
sns.distplot(x, bins=20, kde=False, rug=True)
該函式常用的引數由如下幾個:
- bins:資料的劃分區間;
- kde:進行核密度估計;
- rug:資料在軸上的分佈。
KDE曲線
kdeplot()是對資料進行核密度估計分佈的函式,其中引數shade是控制是否對kde曲線進行陰影填充,bw控制核密度的視窗大小,cut控制曲線切割。
sns.kdeplot(x,shade=True)
sns.kdeplot(x,shade=True,cut=0)
二維分佈圖
散點圖
mean, cov = [0, 1], [(1, .5), (.5, 1)]
data = np.random.multivariate_normal(mean, cov, 200)
df = pd.DataFrame(data, columns=["x", "y"])
sns.jointplot(x="x", y="y", data=df)
六邊圖
x, y = np.random.multivariate_normal(mean, cov, 1000).T
with sns.axes_style("white"):
sns.jointplot(x=x, y=y, kind="hex", color="k");
KDE
sns.jointplot(x="x", y="y", data=df, kind="kde")
f, ax = plt.subplots(figsize=(6, 6))
sns.kdeplot(df.x, df.y, ax=ax)
sns.rugplot(df.x, color="g", ax=ax)
sns.rugplot(df.y, vertical=True, ax=ax)
星雲圖
f, ax = plt.subplots(figsize=(6, 6))
cmap = sns.cubehelix_palette(as_cmap=True, dark=.2, light=1, reverse=True)
sns.kdeplot(df.x, df.y, cmap=cmap, n_levels=60, shade=True)
關係圖
iris = sns.load_dataset("iris")
sns.pairplot(iris)
g = sns.PairGrid(iris)
g.map_diag(sns.kdeplot)
g.map_offdiag(sns.kdeplot, cmap="Blues_d", n_levels=6)
類別資料
散點圖
有時候,我們需要對資料按照某一個屬性進行繪製觀察,而seaborn也提供了這些函式。
# 按tips資料中橫軸為“day”的屬性進行“total”展示
tips = sns.load_dataset("tips")
sns.stripplot(x="day", y="total_bill", data=tips)
這些資料有的地方重疊了,指定引數jitter能將資料散開:
sns.stripplot(x="day", y="total_bill", data=tips,jitter=True)
另一個方法是使用swarmplot函式進行繪製,該函式使用了演算法將點進行散佈,避免重疊:
sns.swarmplot(x="day", y="total_bill", data=tips)
而有時候,這些點也是有類別的,按照上述的分類繪製無法觀測不同類別的點的分佈,hue引數能解決這一點:
sns.swarmplot(x="day", y="total_bill", hue="sex", data=tips)
盒箱圖
sns.boxplot(x="day", y="total_bill", hue="time", data=tips)
小提琴圖
sns.violinplot(x="total_bill", y="day", hue="time", data=tips)
由於小提琴圖是和kde估計相關的,所以同樣提供了一些引數來控制kde估計:
sns.violinplot(x="total_bill", y="day", hue="time", data=tips,
bw=.1, scale="count", scale_hue=False)
同樣也可以對小提琴圖進行類別繪製:
sns.violinplot(x="day", y="total_bill", hue="sex", data=tips, split=True)
可以結合小提琴圖和前面的圖一起顯示:
sns.violinplot(x="day", y="total_bill", data=tips, inner=None)
sns.swarmplot(x="day", y="total_bill", data=tips, color="w", alpha=.5)
柱狀圖
sns.barplot(x="sex", y="survived", hue="class", data=titanic)
點線圖
sns.pointplot(x="sex", y="survived", hue="class", data=titanic)
也可以對其外觀進行設定:
sns.pointplot(x="class", y="survived", hue="sex", data=titanic,
palette={"male": "g", "female": "m"},
markers=["^", "o"], linestyles=["-", "--"])
線性關係圖
個人感覺在實際中用得很少,需要可參考這裡。