# Lesson 9 | 簡易繪圖功能
## 第一節:基礎繪圖函數簡介-1(1)
* 在清理完資料後,我們可以透過視覺化的方式來做資料探勘,同樣的資訊,使用圖像相呈現較於表格/文字,通常能讓閱讀者更快的獲得資訊。
* 相信同學們對安裝套件已經不陌生,在這堂課將帶著同學們使用常見的第三方套件[Matplotlib](https://matplotlib.org/)進行視覺化,我們可以在其[官方網站](https://matplotlib.org/stable/users/getting_started/)看到安裝說明。

* 安裝成功後,我們試著載入Matplotlib套件。
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 200)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
```
## 第一節:基礎繪圖函數簡介-1(2)
* ```Matplotlib```要怎麼畫圖呢?我們可以以這樣的方式去載入模組,並用```subplots```來先宣告我們的圖(```Figure```)跟可以放入資料的軸(```Axes```)。
```python=
# 在Jupyter裡面,圖會被自動化出。
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
```
```python=
# 你也可以呼叫fig這個物件來顯示圖。
fig
```
## 第一節:基礎繪圖函數簡介-1(3)
* 讓我們來透過視覺化來探勘[這個](https://linchin.ndmctsgh.edu.tw/data/Example_data.csv)模擬的醫學資料吧,請先下載!
* 可以使用```Pandas```套件將資料讀進Python。
```python=
import pandas as pd
data = pd.read_csv("Example_data.csv")
data
```
* 讓我們先從幾個簡單的統計圖開始,記得要先去除NA值。
1. 直方圖:需要使用函數「.hist()」
```python=
fig, ax = plt.subplots()
clean_eGFR = data['eGFR'][pd.isnull(data['eGFR']) == False]
ax.hist(clean_eGFR)
```
2. 盒鬚圖:需要使用函數「.boxplot()」
```python=
fig, ax = plt.subplots()
clean_eGFR = data['eGFR'][pd.isnull(data['eGFR']) == False]
ax.boxplot(clean_eGFR)
```
3. 圓餅圖:需要使用函數「.pie()」以及```pandas```的函數「.value_counts()」
```python=
fig, ax = plt.subplots()
clean_edu = data['Education'][pd.isnull(data['Education']) == False]
ax.pie(pd.value_counts(clean_edu))
```
4. 長條圖:需要使用函數「.barplot()」以及```pandas```的函數「.value_counts()」
```python=
fig, ax = plt.subplots()
clean_edu = data['Education'][pd.isnull(data['Education']) == False]
ax.bar(list(set(clean_edu)), pd.value_counts(clean_edu))
```
## 第一節:基礎繪圖函數簡介-1(4)
* 這些圖都能透過增加不同的參數增加變化,我們可以透過[官方說明文件](https://matplotlib.org/stable/api/index.html)來查詢它們內部的參數。舉例來說,我們可以用下列方式改變圖的顏色
- 在[這裡](https://matplotlib.org/stable/gallery/color/named_colors.html),我們可以看到關於顏色的說明。
- 另外,我們可以用這樣的方式,把4張圖放在同一張畫布內:
```python=
clean_eGFR = data['eGFR'][pd.isnull(data['eGFR']) == False]
clean_edu = data['Education'][pd.isnull(data['Education']) == False]
fig, ax = plt.subplots(2, 2)
ax[0,0].hist(clean_eGFR, color = 'purple')
ax[0,1].boxplot(clean_eGFR, boxprops = {'color': 'blue'})
ax[1,0].pie(pd.value_counts(clean_edu), colors = ['yellow', 'green', 'black'])
ax[1,1].bar(list(set(clean_edu)), pd.value_counts(clean_edu), color = 'red')
```
* 你如果喜歡你畫的圖,可以透過```Figure```的方法「.savefig()」把圖片存出去。
```python=
fig.savefig("test.pdf")
```
## 練習1:
* 請練習看[官方說明文件](https://matplotlib.org/stable/api/index.html#),查詢該如何完成下面這張圖:

<details>
<summary>解答</summary>
- 你可以在[這裡](https://matplotlib.org/stable/gallery/statistics/boxplot_demo.html#boxplots)找到範例程式碼,可以發現輸入參數使用能儲存多筆資料的```list```即可。
- 關於軸的設定可以在[這裡](https://matplotlib.org/stable/tutorials/introductory/quick_start.html#axes)找到。
```python=
# 資料前處理的熟悉度也是相當重要的。
eGFR_0 = data['eGFR'][data['Disease'] == 0]
eGFR_1 = data['eGFR'][data['Disease'] == 1]
eGFR_0 = eGFR_0[pd.isna(eGFR_0) == False]
eGFR_1 = eGFR_1[pd.isna(eGFR_1) == False]
fig, ax = plt.subplots()
ax.boxplot(
[eGFR_0, eGFR_1], labels = [0, 1],
boxprops = {'color': 'blue'}
)
ax.set_title("eGFR value by Disease status")
ax.set_ylabel("eGFR")
ax.set_xlabel("Disease")
```
</details>
## 第二節:基礎繪圖函數簡介-2(1)
* 接著我們介紹一個強大的函數「.plot()」,他支援了多種不同的圖形,其中最主要的是散布圖:
```python=
SBP = data['SBP'][(pd.isna(data['SBP']) == False) & (pd.isna(data['DBP']) == False)]
DBP = data['DBP'][(pd.isna(data['SBP']) == False) & (pd.isna(data['DBP']) == False)]
fig, ax = plt.subplots()
ax.plot(SBP, DBP, 'o')
ax.set_title("Scatter plot of SBP and DBP")
ax.set_ylabel("DBP")
ax.set_xlabel("SBP")
```
* 其實,我們可以修改點的造型,例如:
```python=
SBP = data['SBP'][(pd.isna(data['SBP']) == False) & (pd.isna(data['DBP']) == False)]
DBP = data['DBP'][(pd.isna(data['SBP']) == False) & (pd.isna(data['DBP']) == False)]
fig, ax = plt.subplots()
ax.plot(SBP, DBP, '4g')
ax.set_title("Scatter plot of SBP and DBP")
ax.set_ylabel("DBP")
ax.set_xlabel("SBP")
```
* 這樣的設定來自於第三個參數```fmt(Format Strings)```,請看[這裡](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.plot.html#matplotlib.axes.Axes.plot)可以找到相關說明。

## 第二節:基礎繪圖函數簡介-2(2)
* 你也可以利用```.plot()```為你的圖形加點東西,例如畫線可以將fmt設為```'-'```:
```python=
x = [1, 4, 7]
y = [2, 9, 6]
fig, ax = plt.subplots()
ax.plot(x, y, '-')
```
* 當然,如果點夠密,你其實可以畫出圓!
```python=
import numpy as np
z = np.array(list(range(1001)))/100
x = np.sin(z)
y = np.cos(z)
fig, ax = plt.subplots()
ax.plot(x, y, '-')
```
## 第二節:基礎繪圖函數簡介-2(3)
* 學會如何畫線以後,我們能夠幫散布圖上加預測線了…
* 我們需要先畫出預測線,這時需要靠第三方套件幫忙,在Python裡[scikit-learn](https://scikit-learn.org/stable/)是最常用來做數據分析以及機器學習的功能強大套件請先安裝:

* 接著,預測線的方程式,需要函數「lm()」幫忙建立。
```python=
from sklearn.linear_model import LinearRegression
SBP = data['SBP'][(pd.isna(data['SBP']) == False) & (pd.isna(data['DBP']) == False)].to_numpy()
DBP = data['DBP'][(pd.isna(data['SBP']) == False) & (pd.isna(data['DBP']) == False)].to_numpy()
SBP = SBP.reshape((SBP.shape[0], 1))
reg = LinearRegression().fit(SBP, DBP)
coef = reg.coef_, reg.intercept_
pred_DBP = SBP * reg.coef_[0] + reg.intercept_
```
* 並把圖畫出:
```python=
fig, ax = plt.subplots()
ax.plot(SBP, DBP, 'ok')
ax.plot(SBP, pred_DBP, '-r')
ax.set_title("Scatter plot of SBP and DBP")
ax.set_ylabel("DBP")
ax.set_xlabel("SBP")
```
## 第二節:基礎繪圖函數簡介-2(4)
* 其實,你還可以為你的圖形加點料…
1. 「text()」可以為你的圖片上加文字描述
```python=
x = (np.array([1, 0, -1, 0])/5) + 0.5
y = (np.array([0, 1, 0, -1])/5) + 0.5
t = ["A", "B", "C", "D"]
fig, ax = plt.subplots()
for i in range(len(x)):
ax.text(x[i], y[i], t[i])
```
2. 「legend()」可以產生註釋,看[這裡](https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html)有更多的說明。
```python=
fig, axs = plt.subplots()
axs.plot([0, 1, 2], [1, 2, 3], label="test1")
axs.plot([0, 1, 2], [3, 2, 1], label="test2")
# Place a legend to the right of this smaller subplot.
fig.legend(loc='outside upper right')
```
## 練習2:
* 你已經會畫長條圖了吧? 請你畫出下面這張圖!

* 資料前處理可以參考以下,兩組檢定後的*p*-value為0.020。
```python=
eGFR_0 = data['eGFR'][data['Disease'] == 0]
eGFR_1 = data['eGFR'][data['Disease'] == 1]
eGFR_0 = eGFR_0[pd.isna(eGFR_0) == False]
eGFR_1 = eGFR_1[pd.isna(eGFR_1) == False]
m0 = np.mean(eGFR_0)
m1 = np.mean(eGFR_1)
sd0 = np.std(eGFR_0)/(sum(data['Disease'] == 0) ** 0.5)
sd1 = np.std(eGFR_1)/(sum(data['Disease'] == 1) ** 0.5)
```
<details>
<summary>解答</summary>
```python=
fig, ax = plt.subplots()
ax.bar("Disease 0", m0, label="Case")
ax.bar("Disease 1", m1, label="Control")
ax.plot([-0.25, 0.25], [m0 - (1.96 * sd0), m0 - (1.96 * sd0)], '-k')
ax.plot([-0.25, 0.25], [m0 + (1.96 * sd0), m0 + (1.96 * sd0)], '-k')
ax.plot([0, 0], [m0 - (1.96 * sd0), m0 + (1.96 * sd0)], '-k')
ax.plot([0.75, 1.25], [m1 - (1.96 * sd1), m1 - (1.96 * sd1)], '-k')
ax.plot([0.75, 1.25], [m1 + (1.96 * sd1), m1 + (1.96 * sd1)], '-k')
ax.plot([1.00, 1.00], [m1 - (1.96 * sd1), m1 + (1.96 * sd1)], '-k')
ax.plot([0, 0, 1, 1], [35, 38, 38, 36], '-k')
ax.text(0.35, 38.5, 'p = 0.020')
ax.set_ylabel("eGFR")
fig.legend(loc='outside upper right')
```
</details>
## 總結
* 本週介紹了簡易的繪圖功能,這讓我們能在Python裡面繪畫,並且由於有能力進行手刻,任意統計圖理論上都能畫出來了!
* 現在你的整個資料分析流程又包含了繪圖了,之後再讓我們學一些更強的功能吧!