Matplotlib 進階

Da-Wei Chiang

大綱

  • 設定畫布大小
  • 建立子圖
  • 主標題設定
  • 子圖物件
  • pyplot方法 vs subplot方法
  • 共享軸距
  • tight_layout

設定畫布大小 - figure函數

plt.figure(num, figsize, facecolor)

'''
num = 數字, 指定第幾張圖表
figsize = 圖表寬高
facecolor = 圖表背景顏色
'''
In [5]:
# 範例 - 設定畫布大小

import matplotlib.pyplot as plt
import numpy as np


y = np.random.randint(10, 20, 10)
print(y)
plt.figure(figsize=(10, 5))
plt.plot(y)
plt.show()
[14 12 18 11 15 17 16 16 13 17]
In [14]:
# 範例 - 設定背景顏色

import matplotlib.pyplot as plt
import numpy as np


y = np.random.randint(10, 20, 10)
print(y)
plt.figure(figsize=(10, 5), facecolor='#aaa')
plt.plot(y, color='#666')
plt.show()
[18 11 12 14 19 15 16 12 11 12]
In [15]:
#範例 - 繪製多張圖表

import matplotlib.pyplot as plt
import numpy as np

chart1_y = np.random.randint(10, 20, 10)
print(chart1_y)

plt.figure(num=1, figsize=(5,5))
plt.plot(chart1_y)
plt.title('Chart 1')
plt.show()

chart2_y = np.random.randint(10, 20, 10)
print(chart2_y)

plt.figure(num=2, figsize=(10,5))
plt.plot(chart2_y)
plt.title('Chart 2')
plt.show()
[18 18 12 13 17 11 19 11 13 14]
[10 18 15 15 13 12 12 13 15 12]

練習

  • 有兩組數據如下
    • 數據一: 隨機產生10個數字, 其數字介於1~50之間
    • 數據二: 數據一資料的平方
  • 分別繪製兩張圖, 圖形設定如下
    • 數據一為折線圖:
      • 圖片寬高為20,10
      • 線條粗度為2
      • 設定軸線對齊圖表左下角
      • 設定x軸刻度為0 ~ 11(字體大小為15)、資料點繪製於1~10的刻度上
      • 線條顏色為虛線橘色、資料點為方形
      • 設定標題、x標籤、y標籤(字體大小為20)
      • 設定隔線
    • 數據二為散佈圖:
      • 圖片寬高為10,10
      • 資料點為青色
      • 資料點的大小為100
      • 設定軸線對齊圖表左下角
      • 設定x軸刻度為0 ~ 11(字體大小為15)、資料點繪製於1~10的刻度上
      • 設定y軸刻度為0 ~ 2500(字體大小為15)
      • 設定標題、x標籤、y標籤(字體大小為20)
      • 設定隔線

建立子圖

  • 子圖是指一個figure中有多張子圖表.
subplot(row, column, index)
In [16]:
## 範例 - 1*2的子圖設定

import matplotlib.pyplot as plt
import numpy as np

num = np.random.randint(1, 10, 10)
print(num)

plt.subplot(1, 2, 1)
plt.plot(num)
plt.subplot(1, 2, 2)
plt.scatter(range(0, 10), num)
plt.show()
[9 4 8 5 1 8 8 3 7 3]
In [15]:
## 範例 - 加大畫布

import matplotlib.pyplot as plt
import numpy as np

num = np.random.randint(1, 10, 10)
print(num)

plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.plot(num)
plt.subplot(1, 2, 2)
plt.scatter(range(0, 10), num)
plt.show()
[6 1 9 2 7 1 8 6 4 1]
In [12]:
## 範例 - 2*2的子圖設定

import matplotlib.pyplot as plt
import numpy as np

num = np.random.randint(1, 10, 10)
print(num)

plt.subplot(2, 2, 1)
plt.plot(num)
plt.subplot(2, 2, 2)
plt.plot(num)
plt.subplot(2, 2, 3)
plt.plot(num)
plt.show()
[8 4 7 7 4 4 4 9 5 4]

上例我們僅僅是繪製三個圖.但圖形的繪製卻不對稱.

因此我們可以規劃子圖的設定

In [19]:
## 範例 - 2*2的子圖設定

import matplotlib.pyplot as plt
import numpy as np

num = np.random.randint(1, 10, 10)
print(num)

plt.subplot(2, 2, 1)
plt.plot(num)
plt.subplot(2, 2, 2)
plt.plot(num)
plt.subplot(2, 1, 2)   #注意設定方式
plt.plot(num)
plt.show()
[6 1 5 5 7 5 5 8 7 6]

練習

  • 請隨機產生10個介於1~10之間的數, 繪製圖片如下

主標題設定

plt.suptitle('text', fontsize=number, c='color')
In [51]:
## 範例

import matplotlib.pyplot as plt
import numpy as np

num = np.random.randint(1, 10, 10)
print(num)
plt.figure(figsize=(10, 5))
plt.subplot(2, 2, 1)
plt.plot(num)
plt.title('Chart one')
plt.subplot(2, 2, 2)
plt.plot(num)
plt.title('Chart two')
plt.subplot(2, 1, 2)
plt.plot(num)
plt.title('Chart three')
plt.suptitle('main title', fontsize=20, c='r')
plt.show()
[2 6 7 5 5 9 5 3 7 6]

子圖的物件

  • 當我們設定plt.subplot時, 則matplotlib會幫我們產生subplot的物件. 我們可透過此物件進行繪圖
In [57]:
## 範例

import matplotlib.pyplot as plt
import numpy as np

num = np.random.randint(1, 10, 10)
print(num)

chart1 = plt.subplot(1, 2, 1)  #注意寫法
chart1.plot(num)
chart2 = plt.subplot(1, 2, 2)  #注意寫法
chart2.scatter(range(0, 10), num)
plt.show()
[6 8 2 3 4 5 9 4 5 6]

先前的繪圖, 我們多為使用matplotlib.pyplot的方法.

當我們建構子圖物件時. 需使用物件方法進行設定

pyplot 方法 vs subplot方法

#pyplot  #subplot 
xlabel = set_xlabel
ylabel = set_ylabel
axis   = axis
xlim   = set_xlim
ylim   = set_ylim
title  = set_title
xticks = xaxis.set_ticks
yticks = yaxis.set_ticks
In [69]:
## 範例

import matplotlib.pyplot as plt
import numpy as np

num = np.random.randint(1, 10, 10)
print(num)

chart1 = plt.subplot(1, 2, 1)  
chart1.plot(num)
chart1.set_title('Chart1')   #object API
chart1.axis([1, 10, 1, 10])  #object API
chart1.set_xlabel('value')   #object API
chart2 = plt.subplot(1, 2, 2)  
chart2.scatter(range(0, 10), num)
plt.title('Chart2')  #plot API
plt.show()
[3 5 7 3 7 5 3 1 8 4]

練習

  • 請自行練習subplot物件方法

共享軸距

plt.subplot(row, column, index, sharex=subplot_object, sharey=subplot_object)
In [79]:
# 範例 - subplot縮寫/共享y軸

import matplotlib.pyplot as plt
import numpy as np
num = np.random.randint(1, 10, 10)
print(num)

chart1 = plt.subplot(1, 2, 1)  
chart1.plot(num)
chart1.set_title('Chart1')
chart1.axis([1, 10, 1, 10])  

chart2 = plt.subplot(122, sharey=chart1)  
chart2.scatter(range(0, 10), num)
chart2.set_title('Chart2')
plt.show()
[9 9 2 4 8 5 2 6 4 7]
In [100]:
# 範例 - subplot縮寫/共享x軸

import matplotlib.pyplot as plt
import numpy as np
num = np.random.randint(1, 10, 10)
print(num)

plt.figure(figsize=(10, 5))
chart1 = plt.subplot(211)  
chart1.plot(num)
chart1.set_title('Chart1')
chart1.set_xlim(1, 10)  
chart1.tick_params(axis='x', labelbottom=False)  #注意寫法

chart2 = plt.subplot(212, sharex=chart1)  
chart2.plot(range(0, 10), num)
chart2.set_title('Chart2')
plt.show()
[5 6 9 6 6 9 8 8 4 9]

練習

  • 請繪製sin, cos圖形如下

當繪製子圖時常常會有子圖物件重疊的情況.

我們上述範例的作法為調整figure大小.

再不調整figure的情況下我們可以設定tight_layout方法自動跳整

In [157]:
# 範例

import matplotlib.pyplot as plt
import numpy as np
num = np.random.randint(1, 10, 10)
print(num)

#plt.figure(figsize=(10, 5))
chart1 = plt.subplot(211)  
plt.plot(num)
plt.title('Chart1')

chart2 = plt.subplot(212, sharex=chart1)  
plt.plot(range(0, 10), num)
plt.title('Chart2')
plt.tight_layout() ## 設定layout
plt.show()
[5 4 2 4 4 2 5 7 2 1]
In [158]:
## 範例 - rcParams

import matplotlib.pyplot as plt
import numpy as np
num = np.random.randint(1, 10, 10)
print(num)

plt.rcParams["figure.autolayout"] = True   #等同設定figure_layout效果

#plt.figure(figsize=(10, 5))
chart1 = plt.subplot(211)  
plt.plot(num)
plt.title('Chart1')

chart2 = plt.subplot(212, sharex=chart1)  
plt.plot(range(0, 10), num)
plt.title('Chart2')
plt.show()
[5 3 5 6 9 6 4 1 5 9]

練習

  • 請自行練習figure_layout方法