甲居工作室

2. Matplotlib套件 (視覺化資料)

日期:2024/04/17

2. NumPy 套件 (視覺化資料)

Matplotlib 是 Python 中一個常用的繪圖庫,可以與 NumPy 一起用來繪製各種類型的圖表。在進行開始之前,請確認已經安裝了 Matplotlib。

2.1 中文字體

我們先去下載中文字體,推薦使用 Google Font Noto Sans Traditional Chinese

  1. import matplotlib as mpl
  2. import matplotlib.pyplot as plt
  3. from matplotlib.font_manager import fontManager
  4. fontManager.addfont('字體路徑')
  5. mpl.rc('font', family='Noto Sans TC')

依照上述設定即可正常顯示中文,後續程式範例將省略此部分。
WINDOWS 作業系統路徑\需要跳脫字元如下:

  1. fontManager.addfont('C:\\Users\\<username>\\OneDrive\\桌面\\Noto_Sans_TC\\static\\NotoSansTC-Regular.ttf')

2.2 折線圖

  1. # 建立一些示例資料
  2. data = np.arange(10)
  3. # 繪製折線圖
  4. plt.plot(data)
  5. # 添加標題和標籤
  6. plt.title('示例折線圖')
  7. plt.xlabel('X 軸')
  8. plt.ylabel('Y 軸')

plt.plot(x, y):繪製 y 相對於 x 之圖表,如果省略 x,則 x 軸標籤為資料序數。

  • x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

2.3 曲線圖

單線

  1. x = np.linspace(0, 10, 100) # 在 0 到 10 之間生成 100 個等間距的數字
  2. y = np.sin(x) # 計算正弦值
  3. # 繪製曲線圖
  4. plt.plot(x, y)
  5. # 添加標題和標籤
  6. plt.title('正弦曲線')
  7. plt.xlabel('x')
  8. plt.ylabel('sin(x)')

多線

  1. x = np.linspace(0, 10, 100) # 在 0 到 10 之間生成 100 個等間距的數字
  2. y1 = np.sin(x) # 計算正弦值
  3. y2 = np.cos(x) # 計算餘弦值
  4. # 繪製曲線圖
  5. plt.plot(x, y1, label='sin(x)')
  6. plt.plot(x, y2, label='cos(x)')
  7. # 添加標題和圖例
  8. plt.title('正弦值 / 餘弦值')
  9. plt.legend(loc='best')

legend()如不傳入任何額外參數時,將自動決定要新增至圖例的元素。

位置字符串位置代碼位置字符串位置代碼
'best' (僅限軸)0'center left'6
'upper right'1'center right'7
'upper left'2'lower center'8
'lower left'3'upper center'9
'lower right'4'center'10
'right'5

2.4 線條樣式

plot() 函式也接受顏色與線條樣式,例如:

  1. plt.plot(x, y, color='g', linestyle='--', marker='o') # 綠虛線圓圈標記

也可以不使用關鍵字參數,[color][marker][line]也支援其他組合,但請注意,它們的解析可能不正確。例如'go--''g--o' 皆可。

  1. plt.plot(x, y, 'g--o') # 綠虛線圓圈標記

標記(Markers)

字符描述字符描述
‘.’點標記‘,’像素標記
‘o’圓圈標記‘v’向下三角形標記
‘^’向上三角形標記‘<’向左三角形標記
‘>’向右三角形標記‘1’向下三角形標記
‘2’向上三角形標記‘3’向左三角形標記
‘4’向右三角形標記‘8’八邊形標記
‘s’方形標記‘p’五邊形標記
‘P’填充的加號標記‘*’星形標記
‘h’六邊形1標記‘H’六邊形2標記
‘+’加號標記‘x’x標記
‘X’填充的x標記‘D’菱形標記
‘d’細菱形標記‘|’垂直線標記
‘_’水平線標記

線條樣式(Line Styles)

字符描述字符描述
'-'實線'-.'點虛線
'--'虛線':'點線

顏色(Colors)

字符顏色字符顏色
'b'藍色'm'洋紅色
'g'綠色'y'黃色
'r'紅色'k'黑色
'c'青色'w'白色

如果顏色是格式字串的唯一部分,您也可以使用任何matplotlib.colors規範,例如全名 ( 'green') 或十六進位字串 ( '#008000')。

2.4 長條圖/直方圖

  1. # 準備數據
  2. categories = ['A', 'B', 'C', 'D', 'E']
  3. values = [23, 45, 56, 78, 33]
  4. # 繪製長條圖
  5. plt.bar(categories, values)
  6. # 添加標題和標籤
  7. plt.title('示例長條圖')
  8. plt.xlabel('Categories')
  9. plt.ylabel('Values')

bar() 改為 barh(),就會變成水平的長條圖。

  1. # 準備數據
  2. categories = ['A', 'B', 'C', 'D', 'E']
  3. values = [23, 45, 56, 78, 33]
  4. # 繪製水平長條圖
  5. plt.barh(categories, values)
  6. # 添加標題和標籤
  7. plt.title('示例水平長條圖')
  8. plt.xlabel('Values')
  9. plt.ylabel('Frequency')

如果資料量很多時我們可以使用bins將數據分組,取最大值與最小值的差,再除以分組數量,即為每個分組的數值範圍。

  1. # 生成隨機數據
  2. data = np.random.randn(1000)
  3. # 繪製直方圖
  4. plt.hist(data, bins=10)
  5. # 添加標題和標籤
  6. plt.title('示例分組直方圖')
  7. plt.xlabel('Values')
  8. plt.ylabel('Frequency')

有連續性的圖形才能省略 x

2.4 散布圖

散布圖

  1. # 生成隨機數據
  2. data = np.random.randn(1000)
  3. # 繪製直方圖
  4. plt.hist(data, bins=10)
  5. # 添加標題和標籤
  6. plt.title('示例分組長條圖')
  7. plt.xlabel('Values')
  8. plt.ylabel('Frequency')

大小散布圖

  1. # 生成隨機數據
  2. x = np.random.randn(30)
  3. y = np.random.randn(30)
  4. sizes = np.random.rand(30) * 1000
  5. # 繪製散布圖
  6. plt.scatter(x, y, s=sizes)
  7. # 添加標題和標籤
  8. plt.title('大小散布圖')
  9. plt.xlabel('X')
  10. plt.ylabel('Y')

散布圖

  1. # 生成隨機數據
  2. x = np.random.randn(20)
  3. y = np.random.randn(20)
  4. sizes = np.random.rand(20) * 100
  5. colors = np.random.rand(20)
  6. # 繪製散布圖
  7. plt.scatter(x, y, s=sizes, c=colors, cmap='viridis')
  8. # 添加標題和標籤
  9. plt.title('顏色散布圖')
  10. plt.xlabel('X')
  11. plt.ylabel('Y')
  12. # 顯示顏色條
  13. plt.colorbar(label='色彩值')

2.5 圓餅圖

圓餅圖

  1. # 數據
  2. labels = ['A', 'B', 'C', 'D']
  3. sizes = [15, 30, 45, 10]
  4. # 繪製圓餅圖
  5. plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)
  6. # 添加標題
  7. plt.title('示例圓餅圖')
  8. # 顯示圖形
  9. plt.axis('equal') # 保證圓餅圖是正圓的

中空圓餅圖

我們可以透過 wedgeprops參數字典中設定width達成中空樣式

  1. x = [1, 2, 3, 4, 5]
  2. plt.pie(x,
  3. labels=x,
  4. radius=1.5,
  5. wedgeprops={'linewidth': 3, 'edgecolor': 'w', 'width': 1})

  • radius:圓餅圖的直徑
  • wedgeprops.linewidth: 區塊間的間格
  • wedgeprops.edgecolor: 區塊間的顏色
  • wedgeprops.width:圓餅餅皮厚度

2.6 等高線(輪廓)圖

在開始之前我用簡單的方式來解釋 Numpy 中的 meshgrid()

假設你有兩個一維數組,分別代表 x 和 y 軸的坐標:

  1. x = [1, 2, 3]
  2. y = [4, 5, 6]

如果你想要得到所有可能的 x 和 y 坐標的組合,你可以使用 meshgrid()。讓我們來看看 meshgrid() 的效果:

  1. import numpy as np
  2. x = [1, 2, 3]
  3. y = [4, 5, 6]
  4. X, Y = np.meshgrid(x, y)
  5. print("X 矩陣:")
  6. print(X)
  7. print("Y 矩陣:")
  8. print(Y)
  9. # X 矩陣:
  10. # [[1 2 3]
  11. # [1 2 3]
  12. # [1 2 3]]
  13. # Y 矩陣:
  14. # [[4 4 4]
  15. # [5 5 5]
  16. # [6 6 6]]

現在,可以將 X 和 Y 中的每個值視為一對 x 和 y 坐標。例如,(1, 4)、(2, 4)、(3, 4) 分別是第一列的坐標點,而 (1, 5)、(2, 5)、(3, 5) 分別是第二列的坐標點,以此類推。

這就是 meshgrid() 的作用:它將兩個一維數組轉換為兩個二維矩陣,其中一個矩陣包含了所有可能的 x 坐標,另一個矩陣包含了所有可能的 y 坐標。

contour()

  1. plt.contour(X, Y, Z, levels=10, cmap='viridis', linewidths=2)
  • XY 是網格化的二維坐標矩陣。
  • Z 是與 XY 對應的二維數值矩陣,表示需要繪製等高線的數據。
  • levels 參數指定等高線的數量或值。可以是一個整數,表示等高線的數量,也可以是一個列表,表示特定的等高線值。
  • cmap 參數指定了等高線的顏色映射,控制等高線的顏色。
  • linewidths 參數指定了等高線的線寬。
  1. # 定義 x 和 y 的數據範圍
  2. x = np.linspace(-3, 3, 3)
  3. y = np.linspace(-3, 3, 3)
  4. # 將 x 和 y 網格化
  5. X, Y = np.meshgrid(x, y)
  6. Z = np.array([[1, 0, 1],
  7. [2, 1, 1.5],
  8. [3, 1.5 ,2]])
  9. # 繪製輪廓圖
  10. plt.contour(X, Y, Z, levels=10, cmap='viridis', linewidths=2)
  11. # 標示坐標
  12. for i in range(len(x)):
  13. for j in range(len(y)):
  14. plt.text(x[i], y[j], f'({x[i]:.0f}, {y[j]:.0f})', fontsize=8)
  15. plt.colorbar(label='色彩值')

contourf()

  1. # 定義 x 和 y 的數據範圍
  2. x = np.linspace(-3, 3, 3)
  3. y = np.linspace(-3, 3, 3)
  4. # 將 x 和 y 網格化
  5. X, Y = np.meshgrid(x, y)
  6. Z = np.array([[1, 0, 1],
  7. [2, 1, 1.5],
  8. [3, 1.5 ,2]])
  9. # 繪製輪廓圖
  10. plt.contourf(X, Y, Z, levels=10, cmap='viridis')
  11. # 標示坐標
  12. for i in range(len(x)):
  13. for j in range(len(y)):
  14. plt.text(x[i], y[j], f'({x[i]:.0f}, {y[j]:.0f})', fontsize=8)
  15. plt.colorbar(label='色彩值')


contour()contourf() 一個爲線條一個爲填滿的色塊。

contour3D()

  1. # 定義 x 和 y 的數據範圍
  2. x = np.linspace(-3, 3, 3)
  3. y = np.linspace(-3, 3, 3)
  4. # 將 x 和 y 網格化
  5. # 定義 x 和 y 的數據範圍
  6. x = np.linspace(-3, 3, 3)
  7. y = np.linspace(-3, 3, 3)
  8. # 將 x 和 y 網格化
  9. X, Y = np.meshgrid(x, y)
  10. Z = np.array([[1, 0, 1],
  11. [2, 1, 1.5],
  12. [3, 1.5 ,2]])
  13. fig = plt.figure()
  14. ax = plt.axes(projection='3d')
  15. ax.contour3D(X, Y, Z, 50, cmap='viridis')

2.7 等高線(輪廓)圖

  1. # 創建一個新的圖形窗口
  2. fig = plt.figure()
  3. # 添加第一個子圖(2行2列,第1個位置)
  4. ax1 = fig.add_subplot(2, 2, 1)
  5. ax1.plot([1, 4, 3, 5, 2]) # 在第一個子圖中繪製折線圖
  6. # 添加第二個子圖(2行2列,第2個位置)
  7. ax2 = fig.add_subplot(2, 2, 2)
  8. ax2.scatter([1, 2, 3], [4, 5, 6]) # 在第二個子圖中繪製散點圖
  9. # 添加第三個子圖(2行2列,第3個位置)
  10. ax3 = fig.add_subplot(2, 2, 3)
  11. ax3.bar([1, 2, 3], [4, 5, 6]) # 在第三個子圖中繪製長條圖
  12. # 添加第四個子圖(2行2列,第4個位置)
  13. ax4 = fig.add_subplot(2, 2, 4)
  14. ax4.hist([1, 2, 2, 3, 3, 3, 3, 4, 4, 5]) # 在第四個子圖中繪製直方圖

延伸閱讀

3. ngrok

ngrok 是一個方便、安全的工具,可以將本機區域網路連上外部網絡,無需對網路配置進行任何變更,並且有一個網址可供使用讓其他人直接連上該網址的服務或是內容。

Read more

1.Python介紹

我的大學教授曾說過,程式語言是用來「解決問題」的一項工具。因此,這系列教學的目的在於在未來遇到問題時,能為你提供另一個有用的工具。而不是學會程式當個工程師。

Read more