Matplotlib

Table of Contents

Hits

1. Matplotlib 簡介

Matplotlib 是 Python 2D 繪圖的首選工具,無論是學術研究還是資料視覺化,它都是一個非常好用的選擇。

1.1. Matplotlib 是什麼?

Matplotlib 是 Python 中一個非常流行的繪圖套件,主要用來產生各種 2D 圖表。這個工具讓我們可以用程式碼很容易地繪製各種類型的圖形,像是折線圖、長條圖、圓餅圖等。它在學術界和資料科學領域非常受歡迎,因為它強大的功能和簡單的使用方式。

1.2. 兩個重要模組:pylab 和 pyplot

  • pylab:這個模組實作了許多 Matlab 的功能,讓學術界的人能夠輕鬆轉換到 Python 上進行繪圖。pylab 可以被視為 Python 版的 Matlab 繪圖工具。
  • pyplot:這個模組在 pylab 的基礎上加入了 Numpy 支援,讓你可以先用 Numpy 進行數學計算,然後用 pyplot 繪製圖表。這樣你不僅可以進行數據分析,還能把結果視覺化。

1.3. 為什麼使用 Matplotlib?

  • 簡單易用:Matplotlib 的語法非常簡單,初學者可以輕鬆上手。
  • 圖形美觀:它能生成高品質且美觀的圖表。
  • 圖形類型多:除了基本的折線圖、長條圖,還支援更複雜的圖形像是直方圖、熱圖等。
  • 相容於 Matlab:Matplotlib 提供了類似 Matlab 的繪圖方式,對於有 Matlab 經驗的使用者來說,過渡到 Python 的 Matplotlib 會非常順暢。

2. Matplotlib 基本語法

2.1. 基本語法:

在 Matplotlib 中,我們可以使用 matplotlib.pyplot 來繪製各種圖形。最常用的函式是 plt.plot(),它可以用來繪製折線圖、函數曲線等。

2.1.1. plt.plot()

  • 要使用 plt.plot() 繪製圖形,我們需要先匯入 matplotlib.pyplot,並使用 plot() 函式來繪製資料點的連接線條。
  • 語法: plt.plot([x座標資料,] y座標資料 [, 參數1, 參數2, …])
  • plt.plot()官網說明

2.1.2. plt.show() 函式

  • 用來顯示圖形,是每次繪圖後都需要呼叫的函式。當你呼叫這個函式後,圖形會顯示在螢幕上。
  • plt.show()
  • 在colab中不用特別呼叫show(),plot()後的圖會自動顯示

2.1.3. plt.savefig()

如果你想將繪製的圖表儲存到檔案,可以使用 plt.savefig() 函式,它允許你指定檔案路徑和解析度來儲存圖片。

2.2. 範例:簡單的 sin 圖形

  • np.sin()函式為 Numpy 模組求正弦值
  • 請到官網看看除了 sin()還有哪些 function 可以玩,畫出幾個函式曲線
 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: x = np.arange(-3, 3, 0.1)
 5: plt.clf()
 6: plt.plot(x, np.sin(x))
 7: plt.show()
 8: 
 9: # 若要存圖,要先存檔再顯示 # for pycharm
10: # plt.savefig('images/SimpleSin.png', dpi=300)
11: # plt.show()   # for PyCharm

simpleSin.png

Figure 1: 簡單的 sin 圖形

2.3. plot 官方語法

plot()函式控制輸出主要有以下兩類參數:

  • fmt 字串
  • kwarg 參數

基本語法如下:

  • plot([x], y, [fmt], *, data=None, **kwargs)
  • plot([x], y, [fmt], [x2], y2, [fmt2], …, **kwargs)

3. 參數控制

在 Matplotlib 中,我們可以透過 fmt 字串和 kwarg(keyword argument)來控制圖形的外觀。這些參數可以幫助我們設置線條顏色、標記、線型以及其他視覺元素,使得繪製的圖形更加美觀且具有區分性。以下介紹如何使用 fmt 字串和 kwarg 參數來自定義圖表。

3.1. fmt 控制參數

fmt 是一個簡便的字串格式,用來設定線條的顏色、標記和線型。通過簡單的字元組合,我們可以快速控制圖形的基本格式。

3.1.1. 基本語法

plt.plot(x座標, y座標, 'fmt')
  • 顏色(Color):使用單個字母表示顏色,例如 ’r’ 表示紅色,’b’ 表示藍色。
  • 標記(Marker):表示每個數據點的標記形狀,例如 ’^’ 表示上三角形,’o’ 表示圓圈。
  • 線型(Line Style):表示連接數據點的線型,例如 ’-’ 表示實線,’–’ 表示虛線。
字元 顏色 字元 標記 字元 線條
’b’ ’.’ ’–’(兩個-) 虛線
’g’ ’o’ 圓圈 ’-’ 實線
’r’ ’v’ 三角形(下) ’-.’ -.-.-.-.
’c’ ’^’ 三角形(上)    
’m’ 洋紅 ’<’ 三角形(左)    
’y’ ’>’ 三角形(右)    
’k’ ’s’ 正方形    
’w’ ’p’ 五邊形    
    ’*’ *    
    ’+’ +    
    ’x’ x    
    ’d’ 鑽石    

3.1.2. 範例 #1

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: x = np.arange(-3, 3, 0.1)
 5: plt.clf()
 6: plt.plot(x, np.sin(x), 'r+')
 7: plt.show()
 8: 
 9: # saving figure
10: # plt.savefig('images/SimpleSin2.png', dpi=300)
11: 

SimpleSin2.png

Figure 2: 簡單的 sin 圖形

3.1.3. 範例 #2

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: x = np.arange(-3, 3, 0.1)
 5: plt.clf()
 6: plt.plot(x, np.cos(x), 'c-.')
 7: plt.show()
 8: 
 9: # saving figure
10: # plt.savefig('images/SimpleCos.png', dpi=300)

SimpleCos.png

Figure 3: 簡單的 cos 圖形

3.1.4. 範例: 多組資料

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: x1 = np.arange(-3, +3, 0.1)
 5: y1 = np.sin(x1)
 6: y2 = np.cos(x1)
 7: 
 8: #plt.plot(x1, y1, 'r^--', x1, y2, 'go-')
 9: plt.plot(x1, y1, 'r^--', x1, y2, 'go-')
10: plt.savefig('mline.png', dpi=300)

mline.png

Figure 4: 多組圖形

3.2. kwgarg 參數

kwarg 是 Matplotlib 中用來設定繪圖細節的參數,例如顏色、線型、標記、標籤等。

3.2.1. 常見的kwarg參數

  • color:設定線條的顏色,可以使用顏色名稱、字母代碼、色碼或 RGB 值。
  • linestyle:設定線型,如 ’–’ 表示虛線,’-’ 表示實線。
  • marker:設定數據點的標記樣式,如 ’o’ 表示圓圈,’^’ 表示上三角形。
  • label:設定線條標籤,用於圖例顯示。
  • 若 fmt 和 kwarg 設定衝突時,以 kwarg 為主

3.2.2. color

  • 單字,如 g:color = ’lime’
  • 字母,如 g:color = ’k’
  • 色碼,如 g:color = ’#FF0000’
  • RGB 值(0~g1 之間),如:color = (1, 0, 0)
字元 顏色
’b’ 藍色
’g’ 綠色
’r’
’c’ 青色
’m’ 品紅
’y’ 黃色
’k’
’w’ 白色

3.2.3. marker

字元 描述
’.’ 點標記
’,’ 畫素標記
’o’ 圓圈標記
’v’ triangle_down 標記
’^’ triangle_up 標記
’<’ triangle_left 標記
’>’ triangle_right 標記
’1’ tri_down 標記
’2’ tri_up 標記
’3’ tri_left 標記
’4’ tri_right 標記
’s’ 方形標記
’p’ 五角大樓標記
’*’ 星形標記
’h’ hexagon1 標記
’H’ hexagon2 標記
’+’ 加號標記
’x’ x 標記
’D’ 鑽石標記
’d’ thin_diamond 標記
’|’ 圴標記
’_’ 修身標記

3.2.4. linestyle

字元 描述
’-’ 實線樣式
’–’ 虛線樣式
’-.’ 破折號-點線樣式
’:’ 虛線樣式

3.2.5. label

  • fg 呈現線條標籤,如 label = ’y = x^2’
  • 需搭配 pglt.legend()函式方能呈現 label

3.2.6. 其他參數

  • x / y 座標範圍:plt.xlim(起始值, 終止值) / plt.ylim(起, 止)
  • 圖表標題:plt.title(字串)
  • x / y 座標標題:plt.xlabel(字串) / plt.ylabel(字串)
  • 顯示 kwarg 參數裡的 label:plt.legend()

3.2.7. 範例

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: x = np.arange(-3, 3, 0.5)
 5: plt.clf()
 6: plt.plot(x, np.cos(x), color='c', linestyle='--', marker='p')
 7: plt.xlim(-4, 4)
 8: plt.xlabel('This is x label')
 9: plt.title("This is Title", fontsize=16)
10: 
11: plt.savefig('images/kwarg.png', dpi=300)
12: 

kwarg.png

Figure 5: kwarg 參數控制

4. 中文問題

在使用 Python 進行資料視覺化時,如果想要顯示中文(如標題、標籤或圖例中的文字),有時會遇到字型問題,導致中文無法正常顯示。

4.1. 在 PyCharm 中使用中文

PyCharm 中顯示中文的方法主要分為兩步:

  1. 指定字型,使其支援中文。
  2. 解決負號在座標軸上顯示的問題,這是 Matplotlib 中常見的一個問題,當顯示負數時,負號會被當作特殊符號處理。

4.1.1. 範例

1: # 解決中文問題
2: plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 步驟一(替換系統中的字型,這裡用的是Mac OSX系統)
3: plt.rcParams['axes.unicode_minus'] = False  # 步驟二(解決座標軸負數的負號顯示問題)
  • 實際示例

marriage.png

Figure 6: 簡單的折線圖及圖例

4.2. 在 colab 中使用中文

在 Google Colab 中使用中文的過程比較特別,因為 Colab 預設的環境沒有支援繁體中文的字型。我們可以下載一個支援繁體中文的字型,並將其加入到 Matplotlib 的字型列表中來解決這個問題。

  1. 下載台北思源黑體(Taipei Sans TC Beta)字型,這是一個支援繁體中文的免費字型。
  2. 使用 fontManager.addfont() 函式將該字型加入到 Matplotlib 的字型列表中,然後設定為默認字型。

4.2.1. 範例

colab在plot()前先加入下列 cell並執行

 1: # Colab 進行matplotlib繪圖時顯示繁體中文
 2: # 下載台北思源黑體並命名taipei_sans_tc_beta.ttf,移至指定路徑
 3: !wget -O TaipeiSansTCBeta-Regular.ttf https://drive.google.com/uc?id=1eGAsTN1HBpJAkeVM57_C7ccp7hbgSz3_&export=download
 4: 
 5: import matplotlib as mpl
 6: import matplotlib.pyplot as plt
 7: from matplotlib.font_manager import fontManager
 8: 
 9: fontManager.addfont('TaipeiSansTCBeta-Regular.ttf')
10: mpl.rc('font', family='Taipei Sans TC Beta')

5. Legqend

在資料視覺化過程中,圖例(Legend)是一個非常重要的元素,特別當你繪製多條線或多組資料時。圖例可以幫助讀者理解每條線或每組資料所代表的意義。在 Matplotlib 中,我們可以使用 plt.legend() 函式來添加圖例,並自定義圖例的位置。

5.1. plt.legend() 基本語法

  • plt.legend([label1, label2, …]):這個函式用來為每條線添加標籤。標籤的數量應與圖中繪製的線條數一致。
  • loc 參數:用來指定圖例的位置。常用的位置選項有:
    • “upper left”:左上角
    • “upper right”:右上角
    • “lower left”:左下角
    • “lower right”:右下角
    • “best”:Matplotlib 會自動選擇最佳位置,避免與圖形重疊。

5.2. 範例

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: x = np.arange(-3, 3, 0.1)
 5: plt.clf()
 6: plt.plot(x, np.sin(x))
 7: plt.plot(x, np.cos(x))
 8: #加入圖例
 9: plt.legend(["sin", "cos"], loc="upper left")
10: 
11: 
12: # 若要存圖,要先存檔再顯示 # for PyCharm
13: plt.savefig('images/sincoslegend.png', dpi=300)

sincoslegend.png

Figure 7: Caption

6. Line Chart

6.1. Demo #1

如何繪製多組資料的折線圖,包括使用列表和 NumPy 生成資料,並為每條線設置不同的樣式和顏色。

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: x1 = [1, 2, 3, 4, 5, 6]
 5: y1 = [1, 2, 3, 4, 5, 6]
 6: x2 = np.arange(0, 3, 0.3)
 7: x3 = np.arange(8).reshape(2, 4)
 8: print(x3)
 9: print(x3+3)
10: plt.plot(y1, 'c-p', x2, x2**2, 'ms:', x3, x3+3, '-*')
11: plt.savefig('line2.png', dpi=300)
[[0 1 2 3]
 [4 5 6 7]]
[[ 3  4  5  6]
 [ 7  8  9 10]]

line2.png

Figure 8: 簡單的折線圖形 2

6.2. Demo #2

如何使用一個簡單的數學函數(線性函數)繪製折線圖,並為圖表設置標籤與範圍。

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: def angdeg(x):
 5:     return 1.2*x+3
 6: 
 7: x = np.arange(0, 21, 1)
 8: plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 步驟一(替換系統中的字型,這裡用的是Mac OSX系統)
 9: plt.rcParams['axes.unicode_minus'] = False  # 步驟二(解決座標軸負數的負號顯示問題)
10: ax = plt.figure().gca()
11: plt.plot(x, angdeg(x), color='r', linestyle='--', linewidth=3)
12: plt.xlabel('本月闖禍次數', fontsize=16)
13: plt.ylabel('媽媽生氣程度', fontsize=16)
14: plt.xlim(0,21)
15: ax.set_xticks(x)
16: plt.savefig('images/angrymam-1.png', dpi=300)

angrymam-1.png

Figure 9: Angry Mam

6.3. Demo #3

如何使用非線性函數繪製折線圖,並設置 Y 軸範圍以顯示更大區間的資料。

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: def angdeg(x):
 5:     return 500+(x**4)/100
 6: 
 7: x = np.arange(0, 21, 1)
 8: #plt.cla()
 9: plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 步驟一(替換系統中的字型,這裡用的是Mac OSX系統)
10: plt.rcParams['axes.unicode_minus'] = False  # 步驟二(解決座標軸負數的負號顯示問題)
11: 
12: ax = plt.figure().gca()
13: plt.plot(x, angdeg(x), color='r', linestyle='--', linewidth=3)
14: 
15: plt.xlabel('本月闖禍次數', fontsize=16)
16: plt.ylabel('媽媽生氣程度', fontsize=16)
17: plt.xlim(0,21)
18: plt.ylim(0,2201)
19: ax.set_xticks(x)
20: plt.savefig('images/angrymam-2.png', dpi=300)

angrymam-2.png

Figure 10: Angry Mam

6.4. Demo #4

根據條件設定點的顏色、並依資料類型加上legend

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: import pandas as pd
 4: 
 5: def angdeg(x):
 6:     return x**4
 7: def l2c(x):
 8:     if x == True:
 9:         return 'r'
10:     else:
11:         return 'g'
12: 
13: np.random.seed(9527)
14: x = np.random.randint(21, size=20)
15: y = np.random.randint(21, size=20)
16: z = x + y < 20
17: colors = list(map(lambda x: 'g' if x == True else 'r', z))
18: #colors = list(map(l2c, z))
19: labels = list(map(lambda x: '挨揍' if x == True else '平安', z))
20: plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 步驟一(替換系統中的字型,這裡用的是Mac OSX系統)
21: plt.rcParams['axes.unicode_minus'] = False  # 步驟二(解決座標軸負數的負號顯示問題)
22: 
23: ax = plt.figure().gca()
24: 
25: #plt.scatter(x, y, c = colors)
26: rc = [i for i in range(len(colors)) if colors[i] == 'r']
27: gc = [i for i in range(len(colors)) if colors[i] == 'g']
28: 
29: plt.scatter(x[rc], y[rc], c = 'r')
30: plt.scatter(x[gc], y[gc], c = 'g')
31: plt.xlabel('因闖禍受傷程度', fontsize=16)
32: plt.ylabel('因闖禍導致損失金額', fontsize=16)
33: ax.set_xticks(range(21))
34: ax.set_yticks(range(21))
35: plt.legend(['處罰','平安'])
36: plt.plot(x, 20-x, linewidth=3)
37: plt.savefig('images/angrymam-3.png', dpi=300)

angrymam-3.png

Figure 11: Angry Mam

6.5. Demo #5

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: import pandas as pd
 4: 
 5: def angdeg(x):
 6:     return x**4
 7: def l2c(x):
 8:     if x == True:
 9:         return 'r'
10:     else:
11:         return 'g'
12: def mycurv(x):
13:     return 5 + (2 ** (19-float(x)))/6000
14: 
15: np.random.seed(9527)
16: x = np.random.randint(21, size=20)
17: y = np.random.randint(21, size=20)
18: y1 = list(map(mycurv, x))
19: print('y:',y)
20: print('y1:',y1)
21: z = y > y1
22: print('z:', z)
23: colors = list(map(lambda x: 'g' if x == True else 'r', z))
24: colors = list(map(l2c, z))
25: #labels = list(map(lambda x: '挨揍' if x == True else '平安', z))
26: plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 步驟一(替換系統中的字型,這裡用的是Mac OSX系統)
27: plt.rcParams['axes.unicode_minus'] = False
28: # 步驟二(解決座標軸負數的負號顯示問題)
29: ax = plt.figure().gca()
30: #
31: ##plt.scatter(x, y, c = colors)
32: rc = [i for i in range(len(colors)) if colors[i] == 'r']
33: gc = [i for i in range(len(colors)) if colors[i] == 'g']
34: 
35: plt.scatter(x[rc], y[rc], c = 'r')
36: plt.scatter(x[gc], y[gc], c = 'g')
37: plt.xlabel('因闖禍受傷程度', fontsize=16)
38: plt.ylabel('因闖禍導致金錢損失', fontsize=16)
39: ax.set_xticks(x)
40: plt.legend(['處罰
41: ','平安'])
42: x1=np.arange(21,0,-1, dtype=float)
43: print(x1)
44: 
45: plt.plot(x1, 5 + (2 ** (19-x1))/6000, linewidth=3)
46: plt.xlim(0,21)
47: plt.ylim(0,21)
48: ax.set_xticks(range(21))
49: ax.set_yticks(range(21))
50: plt.savefig('images/angrymam-4.png', dpi=300)
y: [15  5  1  1 16 12  6  3 14 15  6 17  2 12  0 11  6  7  9 13]
y1: [48.690666666666665, 5.341333333333333, 5.001333333333333, 5.001333333333333, 5.021333333333334, 5.341333333333333, 5.001333333333333, 48.690666666666665, 5.000083333333333, 5.042666666666666, 5.1706666666666665, 26.845333333333333, 5.001333333333333, 5.010666666666666, 5.021333333333334, 92.38133333333333, 48.690666666666665, 7.730666666666666, 6.365333333333333, 26.845333333333333]
z: [False False False False  True  True  True False  True  True  True False
 False  True False False False False  True False]
[21. 20. 19. 18. 17. 16. 15. 14. 13. 12. 11. 10.  9.  8.  7.  6.  5.  4.
  3.  2.  1.]

angrymam-4.png

Figure 12: Angry Mam

6.6. [課堂練習]繪製折線圖   TNFSH

  1. 利用 list 繪製

    • x1 = [1, 2, 3, 4, 5, 6]

    • y1 = [1, 2, 3, 4, 5, 6]

  2. 執行 plt.plot(y1) 和 plt.plot(x1, y1) 有何差別??
  3. 利用 numpy 繪製

    • x2 = np.arange(0, 3, 0.01)

  4. 執行 plt.plot(x2, x2**2)看看畫出什麼圖形??
  5. 為圖表加上標記、線條標籤,換線條顏色、線條樣式

6.7. [課堂作業]圖表美化   TNFSH

請將下列資料繪成折線圖(男女折線不同顏色、樣式,加標記)

初婚年齡 2006 2011 2014 2015 2016
30.7 31.8 32.1 32.2 32.4
27.8 29.4 29.9 30.0 30.0
  • 圖表標題: Age of first marriage

  • 座標軸標題: x ⇒ Year、y ⇒ Age

  • 線條標籤: 男 ⇒ Male、女 ⇒ Female
  • 結果示例

marriage.png

Figure 13: 簡單的折線圖及圖例

7. Bar chart

在 Matplotlib 中,長條圖有兩種常見形式:垂直長條圖和水平長條圖,分別使用 plt.bar() 和 plt.barh() 函式來繪製。

  • 語法
plt.bar( x座標資料, y座標資料 [, 參數1, 參數2, ...] )
plt.barh( x座標資料, y座標資料 [, 參數1, 參數2, ...] )
  • DEMO
 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: objects = ('Python', 'C++', 'Java', 'Perl', 'Scala', 'Lisp')
 5: performance = [10,8,6,4,2,1]
 6: 
 7: plt.barh(objects, performance, align='center', color = ['b','g','r','c','m','y'], alpha=0.5)
 8: plt.xlabel('Usage')
 9: plt.title('Programming language usage')
10: #plt.show()
11: plt.savefig('barChart.png', dpi=300)

barChart.png

Figure 14: barChart Demo

8. Pie chart

圓餅圖(Pie Chart)是一種常用的視覺化工具,用來展示各部分在整體中所佔的比例。Matplotlib 提供了強大的 plt.pie() 函式,能夠輕鬆製作出美觀的圓餅圖。

8.1. 語法:


plt.pie( 比例列表 [, 參數 1, 參數 2, ...] )

8.2. 參數:

  • colors:設置每個部分的顏色,使用 list 形式,例如 [’red’, ’blue’, ’green’]。
  • labels:設置每個部分的標籤名稱,使用 list 形式。
  • explode:設置部分的突出效果,數值越大,部分突出越明顯,使用 list 形式。
  • autopct:自動顯示每個部分的百分比,格式可以為 ’%3.2f%%’ 表示顯示到小數點後兩位。
  • startangle:設置繪製的起始角度,預設為 0 度。
  • plt.axis(’equal’):確保圖形為正圓形。
  • plt.legend(loc=’位置代碼’):為圖表添加圖例,並設定圖例的位置。
  • legend location
Location String Location Code
’best’ 0
’upper right’ 1
’upper left’ 2
’lower left’ 3
’lower right’ 4
’right’ 5
’center left’ 6
’center right’ 7
’lower center’ 8
’upper center’ 9
’center’ 10

8.3. 範例

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: 
 4: parts = [35.35, 23, 26.65, 15]
 5: labels = ['Harrison', 'Vanessa', 'James', 'Ruby']
 6: colors = ['red', 'lightblue', 'purple', 'yellow']
 7: explodes = [0.1, 0, 0, 0.1]
 8: plt.pie(parts, colors = colors, labels = labels, explode = explodes, autopct = '%3.2f%%')
 9: plt.axis('equal')
10: plt.legend(loc='upper left')
11: 
12: #plt.show()
13: plt.savefig('simplePie.png', dpi=300)

simplePie.png

Figure 15: 簡單的 pie chart

9. 其它圖表

10. 文字註解: plt.text()

在資料視覺化過程中,添加文字註解可以幫助讀者更直觀地了解數據的具體數值或特殊位置。在 Matplotlib 中,我們可以使用 plt.text() 函式來將文字註解放置在圖表上的指定位置。這是一個非常實用的工具,尤其是在展示具體數據點或強調特定資訊時。

10.1. 語法

plt.text(x相對座標, y相對座標, '文字字串', [其它參數])

10.2. 常用參數

  • fontsize:設定字體大小,例如 fontsize=12。
  • color:設定文字顏色,例如 color=’blue’。
  • ha 和 va:分別表示水平和垂直對齊方式,例如 ha=’center’, va=’bottom’。

10.3. 範例

1: import matplotlib.pyplot as plt
2: 
3: x = [1, 2, 3, 4, 5, 6, 7, 8]
4: y = [1, 4, 9, 16, 25, 36, 49, 64]
5: plt.plot(x, y, 'r--')
6: for x, y in zip(x, y):
7:     plt.text(x-0.2, y+0.6, '(%d, %d)' %(x, y))
8: #plt.show()
9: plt.savefig('simpleText.png', dpi = 300)

simpleText.png

Figure 16: 簡單的文字註解

11. 子圖表: plt.subplot()

Matplotlib 提供的 plt.subplot() 函式能夠方便地在一個視窗中繪製多個子圖,將整個繪圖區域劃分為多個區域進行展示。這使得我們可以有效利用圖表空間,同時展示多組不同的數據或圖表。

11.1. subplot 語法

plt.subplot(numRows, numCols, plotNum)
  • 圖表的整個繪圖區域被分成 numRows 行和 numCols 列
  • 然後按照從左到右,從上到下的順序對每個子區域進行編號,左上的子區域的編號為 1
  • plotNum 參數指定創建的 Axes 對象所在的區域
  • 如果 numRows, numCols 和 plotNum 這三個數都小於 10 的話, 可以把它們縮寫為一個整數, 例如 subplot(323) 和 subplot(3,2,3) 是相同的.

11.2. subplots_adjust 語法

plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
  • left:子圖與畫布左邊緣的距離(0 ~ 1 之間的值)。
  • right:子圖與畫布右邊緣的距離。
  • bottom:子圖與畫布底部的距離。
  • top:子圖與畫布頂部的距離。
  • wspace:子圖之間的水平間距。
  • hspace:子圖之間的垂直間距。

11.3. 範例1

 1: import numpy as np
 2: import matplotlib.pyplot as plt
 3: 
 4: from matplotlib.ticker import NullFormatter  # useful for `logit` scale
 5: 
 6: # Fixing random state for reproducibility
 7: np.random.seed(19680801)
 8: 
 9: # make up some data in the interval ]0, 1[
10: y = np.random.normal(loc=0.5, scale=0.4, size=1000)
11: y = y[(y > 0) & (y < 1)]
12: y.sort()
13: x = np.arange(len(y))
14: 
15: # plot with various axes scales
16: plt.figure()
17: 
18: # linear
19: plt.subplot(221)
20: plt.plot(x, y)
21: plt.yscale('linear')
22: plt.title('linear')
23: plt.grid(True)
24: 
25: 
26: # log
27: plt.subplot(222)
28: plt.plot(x, y)
29: plt.yscale('log')
30: plt.title('log')
31: plt.grid(True)
32: 
33: 
34: # symmetric log
35: plt.subplot(223)
36: plt.plot(x, y - y.mean())
37: plt.yscale('symlog', linthreshy=0.01)
38: plt.title('symlog')
39: plt.grid(True)
40: 
41: # logit
42: plt.subplot(224)
43: plt.plot(x, y)
44: plt.yscale('logit')
45: plt.title('logit')
46: plt.grid(True)
47: # Format the minor tick labels of the y-axis into empty strings with
48: # `NullFormatter`, to avoid cumbering the axis with too many labels.
49: plt.gca().yaxis.set_minor_formatter(NullFormatter())
50: 
51: # Adjust the subplot layout, because the logit one may take more space
52: # than usual, due to y-tick labels like "1 - 10^{-3}"
53: plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25, wspace=0.35)
54: 
55: plt.savefig('simpleSubplot.png', dpi = 300)

simpleSubplot.png

Figure 17: 簡單的子圖表

12. [課堂練習]實作   TNFSH

12.1. 方程式圖形

輸入 a, b, c,畫出曲線圖:y=\(ax^2+bx+c\),參考結果如下:

eqcurve.png

Figure 18: 方程式曲線圖

12.2. 成績處理

請複製底下的程式碼:

import numpy as np
scores = [[ 26,  53,  49,  72,  38,  14,  95,  49, 100,  77,  30,  23,  50,  47,  45,  44,  52,  10,  72,  11,  61,  91,   8,  39,  70,  74,  40,  45,  86,   9,],
          [ 68, 100,  97,  80,  63,  31, 100,  45,  92, 100,  54,  20,  78,  52,  62,  65,  85,  48,  90,  60, 100, 100,  56,  56,  62, 100,  37,  55,  91,  46,],
          [ 95,  24,  49,  78,  68,  28,  80,  85,  93,  84,  70,  95,  46,  12,  10,  38,   9,  97,  59,  85,  38,  87,  15,  76,  71,  59,  22,  11,  47,  63,],
          [100,  26,  50,  86,  84,  26,  93,  92,  92,  92,  96, 100,  68,  14,  50,  51,  44, 100,  69, 100,  35,  93,  40,  71,  91,  78,  54,  19,  43,  91,],
          [100,  48,  69,  97,  96,  58, 100,  92,  92,  84,  86, 100,  54,  33,  62,  67,  25, 100,  82, 100,  73,  91,  35,  82,  83,  75,  45,  41,  48,  76,]]

這是一個班級(30名學生)的期中考成績,五科科目名稱: 國文、英文、數學、理化、史地。

作業要求: 以subplot生成4個子圖(2*2),每個子圖25分:

  • 左上圖為五科平均分數的bar chart
  • 右上圖為第一位學生的五科分數組成的pie chart
  • 左下圖為國、英兩科分數所組成的scatter chart
  • 右下圖為數、理化兩科分數所組成的scatter chart

愛心提示: 你最好先把scores這個二維的python list轉換為numpy矩陣,這樣會比較簡單一點…..

參考結果如下:

matplotlibscores.png

Figure 19: 解答範例

12.3. Boxlplot

請自行上網搜尋學習資源下載這個檔案,畫出以下圖形(提示: Google 關鍵字 matplotlib, boxplot)

npbox.png

Figure 20: Caption

13. 其他視覺化模組

13.1. pylab

 1: import numpy as np
 2: import pylab as pl
 3: 
 4: x = np.arange(0.0, 2.0*np.pi, 0.01)
 5: print("x:", x[:5])
 6: y = np.sin(x)
 7: print("y:", y[:5])
 8: 
 9: pl.plot(x,y)
10: pl.xlabel('x')
11: pl.ylabel('y')
12: pl.title('sin')
13: pl.savefig("sinPlot.png")
x: [0.   0.01 0.02 0.03 0.04]
y: [0.         0.00999983 0.01999867 0.0299955  0.03998933]

sinPlot.png

Figure 21: sinPlot

13.2. Bokeh

 1: import numpy as np
 2: from bokeh.plotting import figure, show
 3: from bokeh.io import output_notebook, export_png, output_file, save
 4: import matplotlib.pylab as plt
 5: 
 6: N = 4000
 7: 
 8: x = np.random.random(size=N)*100
 9: y = np.random.random(size=N)*100
10: radii = np.random.random(size=N)*1.5
11: colors = ["#%02x%02x%02x" % (r, g, 150) for r, g in zip(np.floor(50+2*x).astype(int), np.floor(30+2*y).astype(int))]
12: 
13: output_notebook()
14: p = figure(title="Basic Title", plot_width=300, plot_height=300)
15: p.circle(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)
16: output_file('bokehPlot.html', mode='inline')
17: save(p)

bokehPlot.htm

13.3. seaborn

 1: import seaborn as sns
 2: sns.set(style="ticks")
 3: 
 4: #Load the example dataset for Anscombe's quartet
 5: df = sns.load_dataset("anscombe")
 6: 
 7: # Show the results of a linear regression within each dataset
 8: sns.lmplot(x="x", y="y", col="dataset", hue="dataset", data=df, col_wrap=2, ci=None, palette="muted", height=4, scatter_kws={'s' :50,'alpha':1})
 9: 
10: import matplotlib.pyplot as plt
11: #sns.sns_plot.savefig("seabornPlot.png")
12: plt.savefig("seabornPlot.png")

seabornPlot.png

Figure 22: seabornPlot

13.4. Altair

 1: import altair as alt
 2: from vega_datasets import data
 3: 
 4: cars = data.cars()
 5: 
 6: chart = alt.Chart(cars).mark_point().encode( x='Horsepower', y='Miles_per_Gallon', color='Origin').interactive()
 7: 
 8: #import pylab as pl
 9: #pl.savefig("altairPlot.png")
10: chart.save('altairPlot.png', webdriver='firefox')
11: chart.savechart('altairPlot.html')

altairPlot.png

Figure 23: altairPlot

Footnotes:

Author: Yung-Chin Yen

Created: 2024-11-20 Wed 08:41