Matplotlib 基礎

Da-Wei Chiang

大綱

  • 安裝
  • 折線圖
  • 散布圖
  • 綜合應用 - 三角函數
  • 中文字設定

安裝

pip install matplotlib

conda install matplotlib

折線圖

import matplotlib.pyplot

plot(x, y, lw, ls, label, color)

# x : x軸值
# y : y軸值
# lw : 線條寬度(line width)
# ls : 線條樣式(line style)
# label : 圖表標籤
# color : 線條顏色
In [30]:
## 範例

import matplotlib.pyplot as plt

x = [i for i in range(10)]
y = [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
print("x = ", x)
print("y = ", y)
plt.plot(x, y)
plt.show()
x =  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y =  [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
In [1]:
## 範例

import matplotlib.pyplot as plt

y = [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
print("y : ", y)
plt.plot(y)
plt.show()
y :  [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]

練習

  • 請隨機產生10個數(介於1~20之間)
  • 撰寫一個匿名函數, 將這10個數進行平方
  • 請繪製這10個數值的折線圖

設定線條顏色

  • plot方法中增加color參數設定
In [9]:
## 範例

import matplotlib.pyplot as plt

y = [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
print("y : ", y)
plt.plot(y, color='red')
plt.show()
y :  [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]

各類顏色縮寫

b : 藍色
c : 青色
g : 綠色
k : 黑色
r : 紅色
w : 白色
y : 黃色
In [11]:
## 範例

import matplotlib.pyplot as plt

y = [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
print("y : ", y)
plt.plot(y, 'c')   #color參數名稱可不寫
plt.show()
y :  [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]

自定義色碼

plt.plot(data, '16進制色碼')  #16進制色彩設定

plt.plot(data, color=(R/255, G/255, B/255))  #RGB色碼設定, color屬性名稱不可省略

plt.plot(data, color=(R/255, G/255, B/255, A))  #A為透明度設定, 範圍介於0~1
In [13]:
## 範例 - 16進制設定

import matplotlib.pyplot as plt

y = [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
print("y : ", y)
plt.plot(y, '#DB810B')   
plt.show()
y :  [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
In [19]:
## 範例 - RGB設定

import matplotlib.pyplot as plt

y = [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
print("y : ", y)
plt.plot(y, color=((219/255, 129/255, 11/155)))
plt.show()
y :  [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
In [22]:
## 範例 - RGBA設定

import matplotlib.pyplot as plt

y = [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]
print("y : ", y)
plt.plot(y, color=((219/255, 129/255, 11/155, 0.2)))
plt.show()
y :  [7, 7, 10, 1, 2, 9, 7, 1, 1, 2]

練習

  • 請自行練習變更線條顏色

設定軸線

## 設定軸線
axis([x軸起點, x軸終點, y軸起點, y軸終點])

## 查看軸線值
xmin_Variable, xmax_Variable, ymin_Variable, ymax_Variable = plt.axis()
In [2]:
## 範例

import matplotlib.pyplot as plt
import random

y = [random.randint(1, 10) for i in range(10)]
print("y : ", y)
plt.plot(y)
x_min, x_max, y_min, y_max = plt.axis()
print('x min =', x_min)
print('x max =', x_max)
print('y min =', y_min)
print('y max =', y_max)
plt.show()
plt.plot(y)
plt.axis([0, 10, 0, 10])
x_min, x_max, y_min, y_max = plt.axis()
print('x min =', x_min)
print('x max =', x_max)
print('y min =', y_min)
print('y max =', y_max)
plt.show()
y :  [7, 2, 3, 2, 1, 3, 2, 9, 2, 4]
x min = -0.45
x max = 9.45
y min = 0.6
y max = 9.4
x min = 0.0
x max = 10.0
y min = 0.0
y max = 10.0

單設定x或單設定y

## 單設定x軸: 一起設定
plt.xlim(x軸起點, x軸終點)
## 單設定x軸: 分開設定
plt.xlim(x軸起點)
plt.xlim(x軸終點)

## 單設定y軸: 一起設定
plt.ylim(y軸起點, y軸終點)
## 單設定y軸: 分開設定
plt.ylim(y軸起點)
plt.ylim(y軸終點)

## 取得x軸設定
xmin_Variable, xmax_Variable = plt.xlim()
## 取得y軸設定
ymin_Variable, ymax_Variable = plt.ylim()
In [3]:
## 範例

x =  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y =  [5, 2, 9, 6, 1, 2, 6, 10, 2, 5]
plt.xlim(0, 9)
plt.ylim(0, 10)
plt.plot(x, y)
plt.show()

練習

  • 請自行練習軸線設定

繪製格線

plt.grid()
In [2]:
## 範例

import matplotlib.pyplot as plt
import random

y = [random.randint(1, 10) for i in range(10)]
print("y : ", y)
plt.plot(y)
plt.grid()
plt.axis([0, 10, 0, 10])
plt.show()
y :  [8, 1, 5, 2, 1, 1, 6, 2, 3, 5]

設定線條寬度 - 方法一

plot(x, y, lw)
In [11]:
## 範例

import matplotlib.pyplot as plt
import random

y = [random.randint(1, 10) for i in range(10)]
print("y : ", y)
plt.plot(y, lw=10)
plt.grid()
plt.axis([0, 10, 0, 10])
plt.show()
y :  [6, 1, 8, 1, 8, 8, 6, 10, 4, 8]

設定線條寬度 - 方法二

  • 透過rcParams參數設定, 設定方式如下
plt.rcParams['lines.linewidth'] = number


## 注意 - 透過rcParams設定後的參數值會每次繪圖都套用
In [6]:
## 範例

import matplotlib.pyplot as plt
import random

y = [6, 1, 8, 1, 8, 8, 6, 10, 4, 8]
print("y : ", y)
plt.rcParams['lines.linewidth'] = 10
plt.plot(y)
plt.grid()
plt.axis([0, 10, 0, 10])
plt.show()
y :  [6, 1, 8, 1, 8, 8, 6, 10, 4, 8]

設定標題

title(名稱, fontsize=數字)
xlabel(名稱, fontsize=數字)
ylabel(名稱, fontsize=數字)
In [24]:
## 範例
import matplotlib.pyplot as plt
import random

y = [random.randint(1, 10) for i in range(10)]
plt.plot(y, lw=5)
plt.title("Pyplot Example", fontsize=20)
plt.xlabel("Count", fontsize=16)
plt.ylabel("Random Value", fontsize=16)
plt.axis([0, 10, 0, 10])
plt.grid()
plt.show()

設定刻度樣式

tick_params(axis='參數', labelsize=數字, color='顏色')

axis:both(表示x軸及y軸)、xx(表示x軸)、yy(表示y軸)
labelsize:刻度字體大小
color:刻度顏色
In [31]:
## 範例
import matplotlib.pyplot as plt
import random

y = [random.randint(1, 10) for i in range(10)]
plt.plot(y, lw=5)
plt.title("Pyplot Example", fontsize=20)
plt.xlabel("Count", fontsize=16)
plt.ylabel("Random Value", fontsize=16)
plt.axis([0, 10, 0, 10])
plt.grid()
plt.tick_params(axis='both', labelsize=10, color='red')
plt.show()

練習

有個方程式如下
y = 4x+3
請繪製x為1~10時y值的折線圖

請設定折線圖名稱、x軸標籤、y軸標籤、格線、線條顏色設為紅色、線條寬度為10、座標0對準起始點

多組數據設定

plot(xdata, ydata, xdata, ydata...)
In [12]:
## 範例

import matplotlib.pyplot as plt

data1 = [(i*2) for i in range(1, 11)]
data2 = [(i*3) for i in range(1, 11)]
y = [i for i in range(1, 11)]
plt.plot(y, data1, y, data2)
plt.title("Multi Data Chart", fontsize=22)
plt.ylabel("y-Value", fontsize=20)
plt.xlabel("x-Value", fontsize=20)
plt.grid()
plt.show()

線條樣式設定

  • 線條顏色設定
      'b' : blue
      'c' : cyan
      'g' : green
      'k' : black
      'r' : red
      'w' : white
      'y' : yellow
      ...
  • 線條樣式設定
      '-' : solid (預設)
      '--' : dashed
      '-.' : dashdot
      ':' : dotted
      ...
  • 資料點樣式設定
      '.' : 點
      'o' : 圓
      '^' : 三角
      's' : 方形
      '*' : 星形
      '+' : 加號
      '-' : 減號
      ...
In [24]:
## 範例

import matplotlib.pyplot as plt

data1 = [(i*2) for i in range(1, 11)]
data2 = [(i*3) for i in range(1, 11)]
y = [i for i in range(1, 11)]
plt.plot(y, data1, '--o', y, data2, ':^')
plt.title("Multi Data Chart", fontsize=22)
plt.ylabel("y-Value", fontsize=20)
plt.xlabel("x-Value", fontsize=20)
plt.grid()
plt.show()

練習

有三組數據分別如下
    1. 數據一:1, 2, 3, 4, 5 ...共20個數
    2. 數據二:1, 4, 9, 16, 25 ...共20個數
    3. 數據三:1, 3, 6, 10, 15 ...共20個數
請繪製折線圖
    數據一資料點為圓形、數據二資料點為方形、數據三資料點為星形
    數據一資料線為實現、數據二資料線為虛線、數據三資料線為點虛線
    整體圖形設定
        繪製網格
        起始點(0, 0)由左下角開始
        設定圖表名稱為Practice Chart, 字體大小20
        設定x軸名稱為Data Count, 字體大小18
        設定y軸名稱為Value, 字體大小18

練習

各國2018~2020平均月薪如下

台灣:40980, 41883, 42980
日本:87830, 92800, 91245
韓國:82083, 83452, 86521

樣式設定:
    台灣資料點為圓形、線為實線;日本資料點為三角形、線為虛線;韓國資料點為方形、線為點線
    設定圖片名稱為Average Salary, 字體大小20
    設定x軸名稱為Year, 字體大小18
    設定y軸名稱為Salary, 字體大小18

刻度設計

xticks() #設定x軸刻度
yticks() #設定y軸刻度
In [61]:
## 範例

import matplotlib.pyplot as plt

year = [2018, 2019, 2020]
Taiwan = [40980, 41883, 42980]
Japan = [87830, 92800, 91245]
Korea = [82083, 83452, 86521]

plt.plot(year, Taiwan, 'o-', year, Japan, '^--', year, Korea, 's:')
plt.title('Average Salary', fontsize=20)
plt.xticks(year)
plt.xlabel('Year', fontsize=18)
plt.ylabel('Salary', fontsize=18)
plt.show()

圖例

legend(loc='0~10', bbox_to_anchor=(number,number), title="~")

loc : 
    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
In [75]:
## 範例 - 一般圖例

import matplotlib.pyplot as plt

year = [2018, 2019, 2020]
Taiwan = [40980, 41883, 42980]
Japan = [87830, 92800, 91245]
Korea = [82083, 83452, 86521]

#plt.plot(year, Taiwan, 'o-', year, Japan, '^--', year, Korea, 's:')
plt.plot(year, Taiwan, 'o-', label='Taiwan')
plt.plot(year, Japan, '^--', label='Japen')
plt.plot(year, Korea, 's:', label='Korea')
plt.title('Average Salary', fontsize=20)
plt.xticks(year)
plt.xlabel('Year', fontsize=18)
plt.ylabel('Salary', fontsize=18)
plt.legend(loc='best')
plt.show()
In [7]:
## 範例 - 圖外圖例

import matplotlib.pyplot as plt

year = [2018, 2019, 2020]
Taiwan = [40980, 41883, 42980]
Japan = [87830, 92800, 91245]
Korea = [82083, 83452, 86521]

#plt.plot(year, Taiwan, 'o-', year, Japan, '^--', year, Korea, 's:')
plt.plot(year, Taiwan, 'o-', label='Taiwan')
plt.plot(year, Japan, '^--', label='Japen')
plt.plot(year, Korea, 's:', label='Korea')
plt.title('Average Salary', fontsize=20)
plt.xticks(year)
plt.xlabel('Year', fontsize=18)
plt.ylabel('Salary', fontsize=18)
plt.legend(bbox_to_anchor=(1,1))
plt.show()
In [8]:
## 範例 - 設定legend title

import matplotlib.pyplot as plt

year = [2018, 2019, 2020]
Taiwan = [40980, 41883, 42980]
Japan = [87830, 92800, 91245]
Korea = [82083, 83452, 86521]

#plt.plot(year, Taiwan, 'o-', year, Japan, '^--', year, Korea, 's:')
plt.plot(year, Taiwan, 'o-', label='Taiwan')
plt.plot(year, Japan, '^--', label='Japen')
plt.plot(year, Korea, 's:', label='Korea')
plt.title('Average Salary', fontsize=20)
plt.xticks(year)
plt.xlabel('Year', fontsize=18)
plt.ylabel('Salary', fontsize=18)
plt.legend(loc='best', title='location')
plt.show()

儲存圖片

savefig('name.jpg', bbox_inches='tight')
In [24]:
## 範例 - 圖外圖例

import matplotlib.pyplot as plt

year = [2018, 2019, 2020]
Taiwan = [40980, 41883, 42980]
Japan = [87830, 92800, 91245]
Korea = [82083, 83452, 86521]

#plt.plot(year, Taiwan, 'o-', year, Japan, '^--', year, Korea, 's:')
plt.plot(year, Taiwan, 'o-', label='Taiwan')
plt.plot(year, Japan, '^--', label='Japen')
plt.plot(year, Korea, 's:', label='Korea')
plt.title('Average Salary', fontsize=20)
plt.xticks(year)
plt.xlabel('Year', fontsize=18)
plt.ylabel('Salary', fontsize=18)
plt.legend(loc='best', bbox_to_anchor=(1,1))
plt.savefig('Salary.jpg', bbox_inches='tight')
plt.show()

讀取圖片

import matplotlib.image as img

image_Variable = img.imread('name.jpg')
plt.imshow(image_Variable)
plt.show()
In [26]:
## 範例

import matplotlib.pyplot as plt
import matplotlib.image as img

image = img.imread('Salary.jpg')
plt.imshow(image)
plt.show()

去除讀取圖片x軸

plt.axis('off')
In [27]:
## 範例

import matplotlib.pyplot as plt
import matplotlib.image as img

image = img.imread('Salary.jpg')
plt.imshow(image)
plt.axis('off')
plt.show()

練習

全台2019年與2020年當月最高氣溫資料如下

2019 : 31.5, 33.9, 33.8, 38.9, 35, 37.3, 37.4, 37.8, 36.1, 36.7, 31.8, 30.1
2020 : 29.9, 30.3, 34.6, 34.2, 37.3, 37.6, 40.2, 39.1, 38.2, 35.9, 34.4, 29.8

請繪製氣溫折線圖
並回答以下問題
    兩個年度中,哪個年份、哪個月的溫度最高?
    哪個年度的平均氣溫較高?

散佈圖

import matplotlib.pyplot as plt  # 引用

plt.scatter(x, y, s, c)   #繪圖

參數說明
    x, y : (x, y)的位置繪圖
    s : 點的大小
    c: 點的顏色
In [106]:
## 範例 - basic

import matplotlib.pyplot as plt

plt.scatter(3,3)
plt.grid()
plt.axis([1, 5, 1, 5])
plt.show()
In [113]:
## 範例 - 多個點繪製

import matplotlib.pyplot as plt
import random 

xcoor = [1, 2, 3, 4, 5]
ycoor = [random.randint(1, 10) for i in range(5)]
print(ycoor)
plt.scatter(xcoor, ycoor)
plt.show()
[3, 1, 10, 2, 4]
In [118]:
## 範例 - 設定顏色

import matplotlib.pyplot as plt
import random 

xcoor = [1, 2, 3, 4, 5]
ycoor = [random.randint(1, 10) for i in range(5)]
print(ycoor)
plt.scatter(xcoor, ycoor, c="k")
plt.show()
[5, 1, 10, 1, 2]
In [123]:
## 範例 - 設定軸距

import matplotlib.pyplot as plt
import random 

xcoor = [1, 2, 3, 4, 5]
ycoor = [random.randint(1, 10) for i in range(5)]
print(ycoor)
plt.scatter(xcoor, ycoor, c="k")
plt.axis([0, 6, 0, 11])
plt.grid()
plt.show()
[9, 6, 1, 6, 1]

練習

請產生1000個點分別為
[1000平方、999的平方、998的平方...1的平方]
並對這1000個點繪製散步圖
請將顏色設定為黃色

綜合應用 - 三角函數(波形繪製)

正弦 sin
    numpy.sin(弧度)   #sin值

    numpy.deg2rad(角度)  #角度轉換弧度
In [176]:
import numpy as np
import matplotlib.pyplot as plt

xcoor = [i for i in range(810)]
ycoor = [np.sin(np.deg2rad(i)) for i in range(810)]
plt.plot(xcoor, ycoor)
plt.title('Plot Chart')
plt.xlabel('degree')
plt.ylabel('sin Value')
plt.grid()
plt.show()
plt.scatter(xcoor, ycoor)
plt.title('Plot Chart')
plt.xlabel('degree')
plt.ylabel('sin Value')
plt.grid()
plt.show()

練習

  • 請於同一圖表中繪製sin圖形及cos圖形
  • sin請用橘色表示、cos請用深藍色表示
  • x座標僅標示0、90、180、270...810
  • x軸原點請對齊圖形最左邊
  • 繪製圖例

練習

  • 請於同一圖表中繪製sin圖形、2倍sin圖形及0.5倍sin圖形,並觀察其結果
  • 繪製圖例

水平線與垂直線

plt.axhline(y=0, xmin=0, xmax=0, linestyle='style', linewidth='width', color='color')  # 水平線

plt.axvline(x=0, ymin=0, ymax=0, linestyle='style', linewidth='width', color='color')  # 垂直線
In [35]:
## 範例

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['axes.unicode_minus']=False 
xcoor = [i for i in range(810)]
ycoor = [np.sin(np.deg2rad(i)) for i in range(810)]
plt.plot(xcoor, ycoor)
plt.axhline(color='orange', linestyle='-.')
plt.axvline(x=450, ymin=-1, ymax=1, color='red', linestyle=':')
plt.axis()
plt.title('Plot Chart')
plt.xlabel('degree')
plt.ylabel('sin Value')
plt.show()

區間填滿

fill_between(x, y1, y2, color, alpha)   #填滿所有x軸的y1和y2區間,顏色為color,透明度alpha
In [199]:
#範例

import numpy as np
import matplotlib.pyplot as plt

xcoor = [i for i in range(810)]
ycoor = [np.sin(np.deg2rad(i)) for i in range(810)]
plt.plot(xcoor, ycoor, c='#170db5')
plt.title('Plot Chart')
plt.xlabel('degree')
plt.ylabel('sin Value')
plt.axis([0, 810, -1, 1])
plt.xticks([0, 90, 180, 270, 360, 450, 540, 630, 720, 810])
plt.grid()
plt.fill_between(xcoor, 0, ycoor, color='#7bf9ea', alpha=0.3)
plt.show()

練習

  • 承上題練習題
    • 請於同一圖表中繪製sin圖形及cos圖形
    • sin請用橘色表示、cos請用深藍色表示
    • x座標僅標示0、90、180、270...810
    • x軸原點請對齊圖形最左邊
    • 繪製圖例
  • 請將sin正值的部分填滿淡橘色
  • 請將cos負值的部分填滿淡藍色

設定中文字

In [1]:
## 查看設定檔路徑

import matplotlib
print(matplotlib.matplotlib_fname())
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/matplotlib/mpl-data/matplotlibrc

字體下載

下載SimHei.ttf字體

置檔、變更設定及清除快取

  • 置檔
    • 將抓下來的tff檔案放入剛剛查詢到設定檔的相對路徑
      • 如:/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/tff

變更設定

  • 變更設定

    • 進入查詢到的設定檔加入新字體名稱:於#font.serif#font.sans-serif後加入名稱如下

           部分檔案內容如下:
            #font.style:   normal
            #font.variant: normal
            #font.weight:  normal
            #font.stretch: normal
            #font.size:    10.0
      
            #font.serif:      simhei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
            #font.sans-serif: simhei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
            #font.cursive:    Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, Comic Neue, Comic Sans MS, cursive
            #font.fantasy:    Chicago, Charcoal, Impact, Western, Humor Sans, xkcd, fantasy
            #font.monospace:  DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace

清除快取

  • 清除快取
    • 刪除以下路徑的fontlist檔案
        MAC:/Users/使用者名稱/.matplotlib
        Windows:C:\Users\使用者名稱\.matplotlib

程式碼加入中文字設定

import matplotlib as plt

plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
In [9]:
#範例

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif']=['SimHei'] 
plt.rcParams['axes.unicode_minus']=False 

xcoor = [i for i in range(810)]
ycoor = [np.sin(np.deg2rad(i)) for i in range(810)]
plt.plot(xcoor, ycoor, c='#170db5')
plt.title('長條圖 - 中文範例', fontsize=24)
plt.xlabel('角度', fontsize=20)
plt.ylabel('sin角度值', fontsize=20)
plt.axis([0, 810, -1, 1])
plt.xticks([0, 90, 180, 270, 360, 450, 540, 630, 720, 810])
plt.grid()
plt.fill_between(xcoor, 0, ycoor, color='#7bf9ea', alpha=0.3)
plt.show()

練習

  • 承上題練習題
  • 請更改圖中的title名稱,將其改為中文字體