Data Science — Visualization資料科學程式馬拉松

D19-D26

Joe Chao
47 min readMay 24, 2021

D19 Python 資料視覺化工具與常見統計圖表介紹

在不同的領域以及目的中,則會針對圖表呈現有不一樣的要求,如以下例子:

  1. 分析的過程可利用熱點圖來看你的 Deep learning 的 model 是對圖片中哪一部分的看得較重要,可以降維之後將資料視覺化去看資料在空間中的分佈。
  2. 數據呈現成果,以利於表達資料處理結果可用來篩選及醒目提示資料並將複雜、龐大的數據利用長條圖或圓餅圖等方式呈現。

為了要將資料視覺化所需的前置工作:

  1. 制定好主題以及清楚目的;
  2. 釐清測量尺度;
  3. 準確的資料處理與探勘。

Python 資料視覺化主要套件

資料視覺化除了作為最後的結果呈現外,也可看出在分析過程中看出資料間的特徵差異,例如:利用熱點圖可看出在Deep learning 的 model 在圖片中哪部分特徵較為重要,或在降為後將資料視覺化看資料空間的分布,進而決定分析的下一步該如何優化。

Python資料視覺化主要有三大套件:

  1. Matplotlib
  2. Seaborn
  3. Plotly

另外也將介紹兩款具有不同優勢的資料視覺化套件:

  1. Bokeh
  2. Basemap

Matplotlib

  • 是一個最基礎的Python 可視化庫,作圖風格接近 MATLAB,所以稱為 matplotlib。 一般都是從 matplotlib 上手 Python 數據可視化,然後開始做縱向與橫向拓展。
  • matplotlib 的圖像都位於 Figure 物件中
  • 基礎的套件,經典圖表(直方、分箱、…)、多重子圖表(subplot)
  • 其他圖型: 密度圖、等高線圖

Seaborn

  • 基於 matplotlib 的進階視覺化效果庫,針對的點主要是資料挖掘和機器學習中的變數特徵選取,seaborn 可以用短小的代碼去繪製描述更多維度資料的可視化效果圖。
  • Seaborn (靜態的套件)
  • 可以搭配 Matplotlib 建構更直觀的視覺化效果
  • 客製化圖表,進行統計數據可視化:圖表風格與顏色主題 圖表的分面繪製

Plotly

  • 用於繪製互動式圖表的工具庫,基於React、Flask,可於Juputer Notebook 進行線上或離線繪圖,支援Python、MATLAB 和 R 等許多語言。
  • 具備高互動性的圖表以及版面,繪製出來的圖表令人賞心悅目。
  • 將複雜的圖表,用簡單的語法呈現出來。

Bokeh

  • 數據分析的一個業務場景就是用數據講故事,交互資訊可視化的工具就在此凸顯出了優勢。
  • 是一個用於做瀏覽器端交互可視化的庫,實現分析師與數據的交互。
  • Bokeh (動態的套件,類似於 D3.js)
  • 不再需要編輯 HTML 與 JavaScript 便能製作網頁前端視覺化。

Basemap

  • 地理資訊數據也會是部分數據分析師的業務場景。
  • 對於這類數據,可能傳統的 matplotlib/seaborn,互動屬性的 bokeh 無法很好地對這類數據進行處理。我們需要使用處理地理數據引擎更強的可視化工具庫。

Matplotlib 操作方式

在Matplotlib 有兩種主要的操作方式,分別為:

Matplotlib 的全域 pyplot 模組互動操作

  • 若是只有一張圖可以以下語法操作
import matplotlib.pyplot as plt

物件導向形式的操作方式

  • 若是有多張圖的話
  • 透過控制 figure (*.SVG)axis (資料維度) 來操作。
  • 其中 figure 和全域 pyplot 部分屬性相同。例如: fig.text() 對應到 plt.fig_text()

Matpltlib:常用參數說明

Matplotlib.pyplot為包含一系列類似 MATLAB 中繪圖的相關函數,每個Matplotlib.pyplot 中的函數對當前的圖片進行修改,例如:新圖樣的產生或在繪製區域產生標註等。Matplotlib.pyplot會記住目前的圖像以及繪圖區域,進而根據函數設定來在圖像上進行修改。

matplotlib.pyplot.plot 完整指令如下

matplotlib.pyplot.plot(*args,scalex=True,scaley=True,data=None,**kwargs)
  • * args:為 x, y 的特徵;
  • ** kwargs:為指定線標籤、線寬、標記面顏色等屬性設定。
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 5, 0.1)
y = np.sin(x)
plt.plot(x, y,)
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(10)plt.plot(x,x*1.5,'go:',x,x*2.5,'rx',x,x*3.5,'^',x,x*4.5,'bd-.')

Matpltlib:figure 參數說明

Matpltlib.pyplot.figure 完整指令如下:

matpltlib.pyplot.figure(num = None, figsize=None, dpi=None,facecolor=None,edgecolor=None,
frameon=True,FigureClass=<class 'matplotlib.figure.Figure'>,clear=False,
**kwargs)
import matplotlib.pyplot as pltx = np.arange(0, 5, 0.1)
y = np.sin(x)
plt.figure(figsize=(8,6),
facecolor='c')
plt.plot(x,y)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Plot with figsize (8,6)")
plt.show()

Matpltlib:subplot 參數說明

Matpltlib.pyplot.subplot完整指令如下:

matpltlib.pyplot.subplot(nrows, ncols, index, **kwargs)
import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 2) # 建立 2*2 多維視窗
data = pd.Series(np.random.rand(5), index=list('12345'))
#ax為選擇畫圖視窗,color為顏色,alpha為透明度設定
data.plot.bar(ax=axes[0,1], color='b', alpha = 1)
data.plot.barh(ax=axes[1,1], color='b', alpha=0.5)
data.plot.bar(ax=axes[1,0], color='c', alpha = 0.8)
data.plot.barh(ax=axes[0,0], color='r', alpha=0.5)

plt.show()

範例說明:散點圖(Scatter Plots)

散點圖是資料視覺化常用工具之一,與折線圖類似但是這種圖形不使用線段連接,而是使用獨立的點、圓圈或其他形狀呈現。使用Matplotlib,定義x、y軸後,加上圖名和軸名,即可呈現簡潔有力的圖象。

matplotlib.pyplot.scatter 指令完整格式如下

matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None,
vmax=None, alpha=None, linewidths=None, verts=<deprecated parameter>,
edgecolors=None, *, plotnonfinite=False, data=None, **kwargs)
X = np.random.normal(0, 1, 100)
Y = np.random.normal(0, 1, 100)
plt.scatter(X, Y, color='b', alpha=0.5,s=100, edgecolors='red')
plt.title("Scatter plot ")

範例說明:長條圖(Bar Plots)

長條圖、散布圖一樣簡單,用 plt.bar以及 plt.scatter 裡面放你的資料,以及在參數設定風格即可。

長條圖主要用來呈現兩個維度的資料,一個為 X 軸另一個則為 Y 軸(當然這邊指的是二維的狀況,較為常見)

x = np.arange(0., 10., 0.7)
y = np.arange(0., 10., 0.7)
plt.bar(x, y)

優點:

  • 目前Matplotlib為歷史最悠久之視覺化套件,都有足夠的文章、書籍範例可以參考。
  • 對於圖面的需求來說有足夠的彈性調整。

缺點:

  • 圖表呈現較為單調。
  • 畫圖指令複雜。

長條圖 in pandas plot

  • 長條圖,其中資料 index 為 x 軸,欄位部份為 AB 所對應數值,.plot.bar() 會依據所對的數值畫出長條圖。
  • 參數 stacked 可以將長條圖疊加

重點整理

折線圖

  • 適用:會隨時間變動的值
  • 函數 : .plot()

長條圖

  • 適用:不同種類資料,在不同時間點的變化
  • 函數 : .plot.bar()

箱型圖

  • 適用:完整呈現數值分布的統計圖表
  • 函數 : .boxplot()

散佈圖

  • 適用:呈現相關數值間的關係
  • 函數 : .plot.scatter()

D20 使用 Matplotlib 繪製各種常用圖表

# 載入需要的...
import matplotlib.pyplot as plt
import numpy as np
# 準備數據 ... 假設我要畫一個sin波 從0~180度x = np.arange(0,180)
y = np.sin(x * np.pi / 180.0)
# 開始畫圖# 設定要畫的的x,y數據list....plt.plot(x,y)# 設定圖的範圍, 不設的話,系統會自行決定
plt.xlim(-30,390)
plt.ylim(-1.5,1.5)
# 照需要寫入x 軸和y軸的 label 以及title

plt.xlabel("x-axis")
plt.ylabel("y-axis")
plt.title("The Title")

# 在這個指令之前,都還在做畫圖的動作
# 這個指令算是 "秀圖"
plt.show()
import matplotlib.pyplot as pltfig = plt.figure(figsize=(10,6)) #設定 figure 的尺寸
ax1 = fig.add_subplot(3,1,1) #分別畫出三格圖象,都可以針對特定圖象編輯與繪圖
ax2 = fig.add_subplot(3,1,2)
ax3 = fig.add_subplot(3,1,3)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
#設定 figure 的尺寸
fig = plt.figure(figsize=(10,6))
#設定 x , y 數值
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
#設定雙格畫板以及選特定畫板畫圖
plt.subplot(2, 1, 1)
plt.plot(x, y_sin)
#命名圖象
plt.title("Sine")
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
#命名圖象
plt.title("Cosine")
plt.show()

除了 PLT 之外的繪圖:figure 參數說明

matpltlib.pyplot.figure(
num = None,
figsize=None,
dpi=None,
facecolor=None,
edgecolor=None,
frameon=True,
FigureClass=<class 'matplotlib.figure.Figure'>,
clear=False,
**kwargs)
  • num:設定 figure 名稱。系統預設升序命名 figure(透視表輸出視窗)e.g. “figure1”。可自行設定 figure 名稱,名稱或是 INT,或是 str 型別;
  • figsize:設定 figure 尺寸。系統預設命令是 rcParams[“figure.fig.size”] = [6.4, 4.8],即 figure 長寬為 6.4 * 4.8;
  • dpi:設定 figure 畫素密度。系統默命令是 rcParams[“sigure.dpi”] = 100;
  • facecolor:設定 figure 背景色。系統預設命令是 rcParams[“figure.facecolor”] = ‘w’,即白色white;
  • frameon / edgecolor:設定要不要繪製輪廓&輪廓顏色。系統預設繪製輪廓,輪廓染色rcParams[“figure.edgecolor”]=’w’,即白色 white;
  • Figureclass:設定使不使用一個 figure 模板。系統預設不使用;
  • clear:設定當同名 figure 存在時,是否替換它。系統預設 False,即不替換。

除了 PLT 之外的繪圖:plt.text 參數說明

plt.text : 在對應位置加上文字說明來生成相應的數字標籤,舉例:

plt.text(0.5,0.5, ‘axes([0.2,0.2,.3,.3])’,ha=’center’,va=’center’,size=16,alpha=.5)

  • (0.5, 0.5): x、y 值代表了坐標
  • ha=’center’, va= ‘center’代表 horizo​​ntalalignment(水平對齊)、verticalalignment(垂直對齊)的方式
  • size 則是文字大小。alpha 則是透明度

其他的部分的圖標:plt.title, plt.xlabel, plt.ylabel

參數:’欲標示的文字’, fontsize=18,fontfamily = sans-serif’,fontstyle=’italic’

製作繪圖板 Axes

  • Axes 功用與 Subplot 類似,若是在圖形上需要顯示資料的子集,即可使用
  • 但是可以將圖放置在圖中的任何位置。因此,如果要在較大的圖中放置較小的圖,則可以使用軸。
#import matplotlib.pyplot as plt#決定最外框
plt.axes([0.1,0.1,.8,.8])
plt.xticks([]), plt.yticks([])
plt.text(0.6,0.6, 'axes([0.1,0.1,.8,.8])',ha='center',va='center',size=20,alpha=.5)
#決定內框
plt.axes([0.2,0.2,.3,.3])
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'axes([0.2,0.2,.3,.3])',ha='center',va='center',size=16,alpha=.5)
plt.show()

製作 3D 繪圖板

  • 3D 圖形在資料分析、資料建模、圖形和影像處理等領域中都有著廣泛的應用
  • 主要把想要觀察的重點與場景實現兩種交互
  • 一種是可以操縱場景從而能夠從不同的角度觀察模型
  • 一種是擁有添加與操作修改模型物件的能力
#導入必要的模組
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# 創建一個3d坐標系
fig = plt.figure()
ax = Axes3D(fig)
#直接查詢參數與設定
#help(plt.plot)
#help(np.random.sample)
# 利用x軸和y軸繪製sin曲線
x = np.linspace(0, 1, 100) # linspace創建等差陣列
y = np.cos(x * 2 * np.pi) / 2 + 0.5
# 通過zdir = 'z' 將資料繪製在z軸,zs = 0.5 則是將資料繪製在z = 0.5的地方
ax.plot(x, y, zs = 0.5, zdir = 'z', color = 'black', label = 'curve in (x, y)')

D21 使用 Seaborn 進行資料視覺化

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# data 設置
data = np.array([3, 12, 5, 18, 45])
bars = np.array(['A', 'B', 'C', 'D', 'E'])
y_pos = np.arange(len(bars))
plt.yticks([3,5,12,18,45]) # y 軸的刻度值
sns.barplot(y_pos, data, color=(0.2, 0.8, 0.6, 0.6))#color 為 RGB 及 Alpha 調整
plt.legend(['b']) # 左上圖例添加# Custom Axis title 需要調整 matplotlib 設置 x , y座標
plt.xlabel('title of the xlabel', fontweight='bold', color = 'orange', fontsize='17', horizontalalignment='center');
plt.ylabel('title of the ylabel ',fontweight='bold', color = 'r', fontsize='10', horizontalalignment='center')

Seaborn 在底圖背景顯示中,具有五種主題可供選擇,分別為:

1. darkgrid(灰色網格,此為默認主題)

2 . whitegrid(白色網格)

3. dark(黑色)

4. white(白格)

5. ticks(十字交叉)

設定底圖背景樣式:

sns.set_style('darkgrid') # 設定圖形樣式
  • grid:就是圖表當中的格線,這個格線能夠有助於使用者快速地查看圖表當中的數值型資料
  • darkgrid:圖表背景顏色的有,加上格線
  • whitegrid:圖表背景顏色的無,加上格線
  • dark 與 white:就是圖表背景顏色的有無
  • ticks:在 x 軸及 y 軸座標的地方多了一條短短的線,輔助我們去做圖表上的位置核對
def sinplot(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)
# sns.set()
sinplot()
def sinplot(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)
sns.set_style("whitegrid")#加入sns.set_style(),並於括弧內加入欲選擇的主題,如:sns.set_style(whitegrid),
#則可得範例二的圖像。範例三、四、五則以此類推。
sinplot()

seaborn 視覺化線性關係

  • 許多數據集包含多個定量變數,分析的目標通常是將這些變數相互關聯
  • 可以通過顯示兩個變數的關係分佈來完成此目的的函數。可以將通過線性回歸的通用框架實現。
  • Seaborn 的目標是通過視覺化快速輕鬆地流覽數據集,因為這樣做與通過統計表流覽數據集同樣重要
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
sns.lmplot(x="total_bill", y="tip", data= tips)
  • 當 seaborn 的統計估計超越了描述性統計,則可使用 lmplot() 增強散點圖,使其包含線性回歸模型。
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
sns.lmplot(x="total_bill", y="tip", col='time', hue='smoker', data= tips)

seaborn 使用語義映射繪製數據子集

lineplot() 函數 與 scatterplot() 函數具有相同的靈活性,可以透過顏色修改以及大小、樣式來顯示最多三個附加變量。

在 lineplot() 中可使用語義將數據聚合,同時也決定了聚合方式,每一種顏色都有指示分別對應的是哪一個子集。

sns.set(style="whitegrid")
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", kind='line', hue="event" , data=fmri)
sns.set(style="whitegrid")
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", kind='line', hue="region" , style="event", data=fmri)

與散點圖相同,針對多個語義製作線圖,須謹慎使用。在訊息提供時,會再解釋及解析造成困擾,但在一個附加的變量變化有很大的效果,且對於色盲或是黑白印刷時,讓圖象意義更容易讓人理解。

sns.set(style="whitegrid")
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", hue="event", style="event",
kind="line", data=fmri)

seaborn 聚合和表示不確定性

以下範例皆採用 seaborn 內的數據集 — fmri 來使用,首先將資料及匯入:

sns.set(style="dark")
tips = sns.load_dataset("fmri") #載入數據集
tips.sample(50) #可檢視五十筆隨機資料

更複雜的數據質將對 x 變量的相同值進行多次測量,seaborn 的初始默認行為則是通過繪製平均值周周為平均值和 95% 之信賴區間來聚合每個 x 值的多個測量值。

sns.set(style="whitegrid")
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", kind='line',data=fmri)

對於更大的數據,則需透過標準差而非信賴區間表示每個時間點的分布範圍,因此可由以下範例顯示。

sns.set(style="whitegrid")
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", kind='line', ci="sd",
data=fmri)

然而信賴區間是由 bootstrapping 計算而來,針對較龐大的數據量,時間可能為密集型的,可能會影響判斷,因此可以禁用。

sns.set(style="whitegrid")
fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", kind='line', ci= None,
data=fmri)

seaborn 視覺化統計關係

散點圖的關聯變量

以常用的散點圖曲線圖來表示變數之間的關係: sns.relplot()

關注的是統計量之間的關係。 x,y 數值型數據,關注兩個數值變數之間的關係

relplot() — relationship plot

replot 常用參數

  • hue: 在同一維度上,用顏色區分不同數據
  • style: 在同一維度上, 用線的不同表現形式區分, 如 點線, 虛線等
  • size: 控制點大小或者線條粗細
  • kind: 繪製圖的型態. kind= ‘scatter’(散點圖, 預設值) kind=’line’ (線圖),可以通過參數 ci:(confidence interval)參數,來控制陰影部分

散點圖為統計視覺化的支柱,描繪了使用點雲的兩個變量的分布,每一個點則代表數據集的觀察,因此如要觀察兩變量間的分布關係,散點圖為最佳選擇。

#定義主題風格
sns.set(style="darkgrid")
#載入tips
tips = sns.load_dataset("tips")
#繪製圖形,根據不同類型的三點設定圖
sns.relplot(x="total_bill", y="tip", hue="smoker", style="time", data=tips)
plt.show()
#可繪製有漸變效果的散點圖
sns.relplot(x="total_bill", y="tip", hue="size", palette="ch:r=-.5,l=.75", data=tips);
plt.show()

六邊形分箱圖:

六邊形分箱圖為散點圖的延伸,隨著數據量越大畫面的散點越多,數據會重疊再一起也會互相覆蓋,較難看出趨勢集群體。以特定區域為單位,可以統計出這個區域裡散點的頻率,用顏色表示出現頻率高低。

sns.set(color_codes=True)
mean, cov = [0, 1], [(1, .5), (.5, 1)] #設定兩組參數
x, y = np.random.multivariate_normal(mean, cov, 1000).T
with sns.axes_style("ticks"):
sns.jointplot(x=x, y=y, kind="hex", color="r")
plt.show()

熱點圖:

熱點圖為透過不同標示將圖面上或頁面的區域,依照受關注的程度不同來呈現的方式,主要用於離散數據波動變化較大,則可利用熱點圖來觀察。另外則是在相關性中和相關係數的應用中,特徵與特徵間會有相關係數的存在,利用熱點圖可看出特徵與特徵間的相關程度。

flights = sns.load_dataset("flights") # 載入航班數據 
flights = flights.pivot("month", "year", "passengers") #修改數據排列
# 劃分每格單元的行寬度,使用不同的colormap,取消顏色條
sns.heatmap(flights, linewidths=1 , cmap="YlGnBu", cbar=False)
plt.show()

seaborn 視覺化數據集的分佈

在數據處理時,通常會須先了解變數得分布方式,以下將介紹利用 seaborn 來檢測單變量、雙變量的方式進行:

  • 首先先先產生隨機的分布數據,由 numpy 生成,數據類型為 ndarray。
import numpy as np 
import pandas as pd
from scipy import stats, integrate
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes=True)
np.random.seed(sum(map(ord, "distributions")))

繪製單變量分布:

在 seaborn 中,快速觀察單變量分布最快就是使用 distplot() 函數。則會默認圍柱狀圖,並搭配適合得核密度估計(KDE)。

x = np.random.normal(size = 100) 
sns.distplot(x)

直方圖:

確定數量區間後,觀察數據在區間中的特徵形狀,可透過 kde = False 刪除密度曲線,並添加

rug = True , 即可增加每一個觀測值得垂直線。

x = np.random.normal(size=100)
sns.distplot(x, kde=False, rug=True)

可透過 bins 來調整值方圖中的 bins 數量, 若是填 None 則是為默認設定,依照默認範圍指定柱數量。

x = np.random.normal(size=100)
sns.distplot(x, bins=20 , kde=False, rug=True)

核密度估計:

利用核密度估計是用來繪製分布形狀十分有用的工具。有如值方圖,KDE plots 會在一個軸上通過高度變化,沿著其他的軸將觀察到的密度編碼。

x = np.random.normal(size=100)
sns.distplot(x, hist=False, rug=True)

以下則介紹如何將核密度估計曲線,首先將每個觀測值被以該值為中心的正態曲線取代。

x = np.random.normal(0, 1, size=30)
bandwidth = 1.06 * x.std() * x.size ** (-1 / 5.)
support = np.linspace(-4, 4, 200)
kernels = []
for x_i in x:
kernel = stats.norm(x_i, bandwidth).pdf(support)
kernels.append(kernel)
plt.plot(support, kernel, color="r")
sns.rugplot(x, color=".2", linewidth=3)

接下來將取線進行求和,計算每個點的密度值,最終曲線被歸一化,使得曲線下包圍的面積為一。

from scipy.integrate import trapz
density = np.sum(kernels, axis=0)
density /= trapz(density, support)
plt.plot(support, density)

最後可得在 seaborn 使用 kdeplot() 函數,則可得到相同曲線。這個函數如被 displot() 所使用,但如果只想要得到一個密度估計,則可使用 kdeplot() 會為較為容易的選項。

sns.kdeplot(x, shade=True)

繪製雙變量分布:

雙變量的分布對於可視化也是十分有用的,在 seaborn 中 最容易的方式就是使用 joinplot() 函數,可創建多個面板來呈現兩變量之間的關係,以及每軸的單變量分布。

首先將數值分布設定好:

import numpy as np 
import pandas as pd
from scipy import stats, integrate
import matplotlib.pyplot as plt
import seaborn as sns
mean, cov = [0, 1], [(1, .5), (.5, 1)]
data = np.random.multivariate_normal(mean, cov, 200)
df = pd.DataFrame(data, columns=["x", "y"])

散點圖:

雙變量的分布最熟悉的方式為散點圖,在每個觀察結果中以 x 軸與 y 軸值所對應的點表現。 另外也可以使用 matplotlib() 的 plt.scatter 來繪製散點圖。

sns.jointplot(x="x", y="y", data=df)

直方圖 histogram 雙變量 類似圖被稱為 hexbin 圖,因為他展示了落在六角形箱的觀測量,此種的會圖對於相對大的數據集有十分良好的效果。

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");

D22 運用實際資料集進行資料視覺化練習

  • Seaborn 可以直接把 PANDAS 的 dataframe 當成資料匯入,非常方便!
# 導入必要的程式庫
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
# 取得鳶尾花資料集
df = sns.load_dataset('iris')
df.info()
sns.boxplot(data = df, orient = "h")

一些常用參數說明:

  1. hue : 對同一行再進行別的分類。
  2. dodge : 在我用了 hue 之後,那麼數據會變得凌亂,所以我們可以用 dodge 沿著座標軸將再細分的類分開。
  3. orient : 控制方向 (水平或垂直)。

Box plots:包含那筆資料集中的幾個重要資訊

sns.stripplot(x = "species", y = "petal_length", data = df)

常用參數說明:

  • jitter : 若資料集太集中,看起來會變成一直線,這個參數能對他做些干擾 (例如把 uniform distribution 的寬變成 1/2),讓數據看起來較不重疊。
sns.swarmplot(x = "species", y = "petal_length", data = df)

合併使用

sns.boxplot(x = "species", y = "petal_length", data = df)
sns.swarmplot(x = "species", y = "petal_length", data = df)

核密度估計(Kernel Density Estimates, KDE)

  • 所謂核密度估計,就是採用平滑的峰值函數(“核”)來擬合觀察到的數據點,簡單來說,就是把離散轉為連續進行觀察。
  • 曲線圖能更加準確地反映總體的基本變量。以下面 3 個數據點 (5, 10, 15) 的一維數據集為例:

所有平滑的峰值函數均可作為 KDE 的核函數來使用,那我們必須了解甚麼示核函數,核函數要符合:

  1. 正規化 ( 也就是函數下面積的範圍為[0,1] )
  2. K(-u) = K(u)

一些重要特性:

  1. 在數據點處為波峰
  2. 曲線下方面積為 1
  3. 函數曲線需囊括所有可能出現的數據值的情況
sns.set_style("ticks")
sns.pairplot(df,hue = 'species',diag_kind = "kde",kind = "scatter",palette = "husl")

一些常用參數 :

kind:用於控制非對角線 ( 左上至右下 ) 上的圖形,可選 “scatter”(散點圖)與”reg”(回歸直線)。

diag_kind : 用於控制對角線上的圖形,可選”hist”(直方圖)与”kde”(曲線圖)。

觀察上圖:

1 . 可以觀察每個情節的變化。繪圖採用矩陣格式。

2 . 對角線圖是內核密度圖,其中其他圖是散點圖

g = sns.pairplot(df,hue = 'species',diag_kind = "kde",kind = "scatter",palette = "husl")
g.map_upper(plt.scatter)
g.map_lower(sns.kdeplot, cmap = "Blues_d")
g.map_diag(sns.kdeplot, lw = 3, legend = False)

D23 結合 Pandas 與 Matplotlib 進行進階資料視覺化練習

pandas.DataFrame.duplicated:檢查他們是否有重複列

df_white.duplicated().sum(),df_red.duplicated().sum()

我們的資料會變成 Series (一串布林值) ,後面加了.sum() 可以告訴我們有幾列重複 (遇到 True 就會加 1)。

pandas.DataFrame.drop_duplicates:把重複的列刪除。

df_white.drop_duplicates(inplace = True)
df_red.drop_duplicates(inplace = True)

pandas.isnull:檢查是否有空的值

red_df.isnull().sum().sum(), white_df.isnull().sum().sum()

什麼是視覺化?

  • 視覺化是數據分析的一個固有部分,因為它用於以簡單而有效的方式傳達我們的發現,所以我們若熟悉可視化套件,在日後的資料分析上是有很大的幫助的。
  • 大部分的可視化都會利用繪製強大趨勢、圖表和各種其他統計圖表(例如 : 箱型圖、帶狀圖)。
  • 這種對數據的瞭解反過來又有助於預測和模型構建 (例如 : K 線)。
  • 針對紅白酒的資料集,我們會依序使用底下四種圖形作為例子,並說明些圖分別告訴我們那些原本看不到的事情。

以下都是二維圖形喔!

1. 直方圖 : 兩個座標分別為統計樣本數和該樣本對應的某個屬性的度量,以長條圖表線。

2. 熱力圖 : 熱圖也可以簡單分為離散與連續型的,不過在這裡我們以離散型的為主,其中兩

個元素之間的關係量級由色調表示。

3. 聯合圖 : 此圖採用兩個變量或單變量,並同時創建不同圖形在畫紙上。

4. 小提琴圖 : 用來展示資料 (多組) 的分布情形,可以說是箱型圖加上密度圖的結合。

直方圖

直方圖在垂直軸上計數,在水平軸上使用值範圍,例如下圖的垂直軸為樣本數量,水平軸為該度量值。

我們可以從中發現,直方圖可以明顯的讓我們看見資料的集中度。

  • pad 用於設置繪圖區邊緣與畫布邊緣的距離大小
  • w_pad 用於設置繪圖區間水平距離的大小
  • h_pad 用於設置繪圖區間垂直距離的大小
df_wine.hist(bins=10, color='lightblue',edgecolor='blue',xlabelsize=8, ylabelsize=8, grid=False)plt.tight_layout(rect=(1,1,3,3))

熱力圖:熱圖中的梯度根據屬性之間的相關性強度而變化。

f, ax = plt.subplots(figsize=(10, 6))
b = sns.heatmap(df_all.corr(), annot=True, linewidths=.05, ax=ax)
f.subplots_adjust(top=0.93)
bottom, top = ax.get_ylim()
ax.set_ylim(bottom + 0.5, top - 0.5)
title= f.suptitle('Correlation Heatmap for wine attributes', fontsize=12)

聯合圖

聯合圖用於顯示兩個變數之間的關係。

seaborn.jointplot

可以選擇從 5 個選項中選一個製圖 — scatter、reg、hex、kde、resid。

下面我展示了三個使用線性回歸線 (reg)。

  1. 第一個示例”volatile acidity”和”fixed acidity”具有正相關關係,因此圖形是向上的。
  2. 然而,”chlorides”和”alcohol”的變數是相關的。因此,線性回歸線幾乎是平的。
  3. 具有”volatile acidity”和”citric acid”屬性的示例具有負相關性,因此圖呈向下。
sns.jointplot(data=df_wine, x="fixed acidity", y="volatile acidity", kind = 'reg')
sns.jointplot(data=df_wine, x="alcohol", y="chlorides", kind = 'reg')
sns.jointplot(data=df_wine, x="volatile acidity", y="citric acid", kind = 'reg')

小提琴圖

violinplot 與小提琴圖更詳細介紹

seaborn.violinplot

官方網址 : seaborn.violinplot

另一個類似相形圖的可視化效果是小提琴圖,與箱型圖不一樣的地方在於,此圖是使用內核密度圖 (描繪不同值的數據的機率密度) 可視化分組數值數據的另一種有效方法,也就是不是用真實資料點繪製。白點是中位數,小提琴內的黑色條是四分位數範圍(IQR),延伸的黑線是第一個四分位數 = 1.5*IQR,第三四分位數 = 1.5*IQR。小提琴情節的較寬部分表示高概率,較窄的部分表示低概率。

PYTHON 數據可視化

Pandas — Python 讀取 csv 檔、excel 檔及文字檔 txt 的工具套件。

Seaborn 的分布圖是整合了 matplotlib 的直方圖與密度圖(kdeplot)的功能,增加了地毯效果(rug)用來觀測分布,同時也可以使用 fit 參數去擬合分配圖形。

我們可以使用 Matplotlib, Seaborn, Pandas 處理龐大的數據集

  • 條形圖 (Bar plot):條形圖也可稱為柱狀圖,通常用在數值的顯示或者比較。
  • 直方圖 (Hist plot):用於頻率分佈,y 軸表示頻率分佈(數值或者比率),hist 函數柱體個數預設 bins=10,且預設圖中會有網格線。
  • 散點圖能夠顯示 2 個維度上每組數據的值。可以顯示觀察數據分布情形,描述數據的相關性
  • 核密度圖顯示數值變量的分佈,它非常類似於直方圖。
  • 熱力圖是一個以顏色變化來顯示數據的矩陣。簡單來說,就是用依據數字的不同,使用不同的顏色來呈現數據。

數據降維與可視化

目的:

為了讓人們容易理解高維資料的分佈情況及降低後續特徵提取演算量,最常用的方式就是將觀察的資料「降維(Dimensionality Reduction)」到二維或三維空間再進行觀察,亦可看做是將資料從高維度重新投影(Projection)至低維度空間 (但這個不是此堂課的重點)。

推薦查詢關鍵字 : t-SNE、PCA、UMAP

D24 BOKEH 輕鬆以網頁呈現視覺化圖表

Bokeh

  • Bokeh 畫的圖形是一層一層建構起來的,建立一張畫布(figure) → 在畫布中新增圖形符號 (glyphs)
  • glphs 包括圓形(circles) 、補丁(patches)、條形(bars)、弧形(arcs) 等等。
  • Bokeh 為一個 Python 函式庫,提供了各式各樣的視覺化必須的輔助函式,同時也將網頁前端的技術細節包裝成一個個的 Python 函式與參數供我們呼叫,讓我們不再需要編輯 HTML 與 JavaScript 便能製作網頁前端視覺化。

Bokeh 程式的基本運作

要注意的是 bokeh 會預設連 BokehJS cdn,但連線有時不是很穩定,這時可多加”INLINE”環境變數設定,讓 BokehJS 驅動於 local python env。

from bokeh.resources import INLINE
import bokeh.io
bokeh.io.output_notebook(INLINE)

載入套件函數

from bokeh.plotting import figure, show
from bokeh.models import widgets
from bokeh.io import output_notebook, output_file

讓網頁直接輸出在NOTEBOOK

output_notebook()

設定資料與輸出檔案

output_file(“out.html”)

利用 Bokeh 繪製圖表

p = figure()p.line([1,2,3,4,5], [5,4,3,2,1])

開啟產生的 HTML 檔 ( HTML + JavaScript ,自動生成 )

show(p)

Bokeh 也提供了一些預先建置好的圖表供我們使用,例如用 circle 繪製點圖:

p = figure(width=800,height=300)
p.circle([1,2,3],[2,5,3], size=[10,20,30], color=["pink","olive","gold"])
show(p)

除了繪製點圖的 circle 函式以外,另外還有以下不同圖形的繪製函數:

  • bokeh.charts.Bar — 製作長條圖
  • bokeh.charts.BoxPlot — 製作盒鬚圖
  • bokeh.charts.HeatMap — 製作熱圖
  • bokeh.charts.Donut — 製作甜甜圈圖

製作各式圖表, Bokeh 將函式庫大略分成三組:

  • bokeh.model — 製作圖表的基本元素,例如軸線、形狀等等。用來打造各種元件。
  • bokeh.plotting — 為我們處理掉一些基本細節 ( 例如格點與軸線 ) ,但保留客製化的彈性。
  • bokeh.charts — 直接使用各種完整圖表,例如長條圖、盒鬚圖等等。

網頁元件與互動圖表

我們先透過 IFrame 直接呼叫 bokeh 範例來看看。

Ipython.display

可以看到 bokeh 的範例上,有許多互動功能右側更有一排小工具可供使用。

from IPython.display import IFrame
IFrame('https://demo.bokeh.org/sliders', width=900, height=500)

製作互動圖表的能力

由於 Python 並沒有在網頁上執行的能力,這個其實是透過 HTML + Bootstrap 兜起來的元件

製作互動圖表 — CustomJS 回調

JavaScript callbacks

#定義互動過程 (code=”””JavaScript代碼”””)
callback = CustomJS(args=dict(source=source), code="""
var data = source.data;
var f = cb_obj.value
var x = data['x']
var y = data['y']
for (var i = 0; i < x.length; i++) {
y[i] = Math.pow(x[i], f)
}
source.change.emit();
""")
  • 通過 js_on_change 設定 CustomJS 類型的回調函數,將 javascript 代碼寫入 HTML。
  • args 後面為數據的輸入,javascript 中直接使用 source 訪問數據。
  • cb_obj 為觸發回調的模型,可在 javascript 中直接使用,(該 HTML 檔可不依賴 Python Bokeh 就能使用)
#建立並給定部件名稱
slider = Slider(start=0.1, end=4, value=1, step=.1, title="power")
slider.js_on_change('value', callback)
  • 此處的 ’value’ 對應上面 JavaScript 代碼的 value,並且定義透過 slider 物件,來改變 callback 裡面的 value,而 CustomJS 觸發回調的模型,以 cb_obj 物件存取。

Creating layouts

# 建立頁面框架
layout = column(slider, plot)
# 結果呈現
show(layout)

CustomJS 選擇

  • 另一個常見的情況是,當選擇更改時,希望指定要執行的相同類型的回調。作為簡單的演示,下面的示例僅將第一個圖上的選定點複製到第二個圖上。但是,可以採用類似的方式輕鬆構造更複雜的動作和計算。

JavaScript callbacks

# customjs for selectionsfrom random import randomfrom bokeh.layouts import row
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.plotting import figure, output_file, show
# 儲存 HTML 檔案
output_file("callback.html")
x = [random() for x in range(500)]
y = [random() for y in range(500)]
s1 = ColumnDataSource(data=dict(x=x, y=y))
p1 = figure(plot_width=400, plot_height=400, tools="lasso_select", title="Select Here")
p1.circle('x', 'y', source=s1, alpha=0.6)
s2 = ColumnDataSource(data=dict(x=[], y=[]))
p2 = figure(plot_width=400, plot_height=400, x_range=(0, 1), y_range=(0, 1),
tools="", title="Watch Here")
p2.circle('x', 'y', source=s2, alpha=0.6)
s1.selected.js_on_change('indices', CustomJS(args=dict(s1=s1, s2=s2), code="""
var inds = cb_obj.indices;
var d1 = s1.data;
var d2 = s2.data;
d2['x'] = []
d2['y'] = []
for (var i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y'].push(d1['y'][inds[i]])
}
s2.change.emit();
""")
)
layout = row(p1, p2)show(layout)

邊緣和節點渲染器 GraphRenderer

關鍵功能是它為圖節點和圖邊緣維護單獨的 sub-GlyphRenderer。

  • 這樣可以通過修改 GraphRenderer 的 node_renderer 屬性來自定義節點。可以將 Circle 節點的默認字形替換為任何 XYGlyph 實例,例如 Rect 或 Ellipse 字形。
  • 同樣,可以通過 edge_renderer 屬性修改邊緣的樣式屬性。

交互策略

通過設置 GraphRenderer 的 selection_policy 和 inspection_policy 屬性,可以配置圖形的選擇或檢查行為。這些策略屬性接受特殊的 GraphHitTestPolicy 模型實例。

例如,設置 selection_policy = NodesAndLinkedEdges()將使所選節點也選擇關聯的邊。類似地,設置 inspection_policy = EdgesAndLinkedNodes()將導致在使用 HoverTool 懸停邊線時也檢查邊線的起點和終點。

用戶可能希望自定義邊緣和節點子渲染器的 selection_glyph,nonselection_glyph 和 / 或 hover_glyph 屬性,以便將動態視覺元素添加到其圖形交互中。

import networkx as nx#建立互動網路圖
G=nx.karate_club_graph()
#載入相關的套件
from bokeh.io import output_file, show
from bokeh.models import (BoxSelectTool, Circle, EdgesAndLinkedNodes, HoverTool,
MultiLine, NodesAndLinkedEdges, Plot, Range1d, TapTool,)
from bokeh.palettes import Spectral4
from bokeh.plotting import from_networkx
#建立互動網路圖
G=nx.karate_club_graph()
plot = Plot(plot_width=400, plot_height=400,
x_range=Range1d(-1.1,1.1), y_range=Range1d(-1.1,1.1))
plot.title.text = "Graph Interaction Demonstration"
plot.add_tools(HoverTool(tooltips=None), TapTool(), BoxSelectTool())graph_renderer = from_networkx(G, nx.circular_layout, scale=1, center=(0,0))#建立節點交互
graph_renderer.node_renderer.glyph
#建立邊緣回饋交互
graph_renderer.edge_renderer.glyph
#選擇策略
graph_renderer.selection_policy = NodesAndLinkedEdges()
graph_renderer.inspection_policy = EdgesAndLinkedNodes()
#繪製GRAPH
plot.renderers.append(graph_renderer)
#輸出
output_file("interactive_graphs.html")

D25 Basemap 進行地理資訊繪圖(略)

D26 使用 PANDAS 與 BASEMAP 將數據整合於地理資訊圖表(略)

--

--

Joe Chao

會計背景,但目前在管顧實習。喜歡很多事情,於是都選擇把它一一記錄下來。