Hello Matplotlib！
By: Mape Academy
Tags: Machine Learning, Python, Matplotlib, Data Science, Data Visualization

Matplotlib Introduction

在大數據應用的時代，除了將資料分析後的結果具體呈現之外，總希望可以在整個分析過程當中利用資料視覺化來看出一些有趣及重要的insight，尤其在大數據下的機器學習及人工智慧應用更是重要。Matplotlib是Python當中用來繪圖、圖表呈現及數據表示非常重要的一個Package。Matplotlib是一個功能強大的開源(Open Source)工具包，用於表示及可視覺化數據，創建者John Hunter深受MATLAB程式環境的啟發，所以蘊藏了一些其元素想法。由於網路上得到的資料大都較為混亂，本系列文章希望透過對工具包進行結構化介紹後來嘗試為初學者揭開Matplotlib一些神秘的面紗，首先我們先將重點放在Matplotlib的架構及基礎知識，並且了解如何利用數據來創建圖形並進而客製化圖形。

1.Matplotlib Architecture

Matplotlib的架構主要分三個部分，分別是Backend Layer、Artist Layer及Scripting Layer，每一個Layer都有其負責的功能如下：

Backend Layer

網路上有許多參考資料都提到matplotlib的Backend Layer，但對於初學者往往會對於一些術語及解釋感到困惑，我試著用比較簡單的方式說明。在使用matplotlib來繪圖或製作數據圖表時，由於每個人的開發環境或練習的介面不同，為了要能有效呈現其強大的繪圖功能，就必須有對應支援的backend來溝通，例如有些人是利用python shell來跟matplotlib進行互動，此時你可以輸入下列資料，你將得到此時用的backend是’TkAgg’來幫你完成你所要的功能。

>>> import matplotlib.pyplot as plt

>>> plt.get_backend()

‘TkAgg’

如果你是在Jupyter Notebook當中使用inline的方式來進行互動，那你鍵入下列資料將得到此時的backend是’nbAgg’(如下圖)

當然因應不同使用者的環境及需求，所對應的後端(backend)也會不一樣，而為了支援這些不一樣的使用情況，matplotlib可以定義不同的輸出功能，並且由使用者前端的程式代碼(繪圖代碼)，交給後端來完成工作並製作漂亮或複雜的圖形。

Artist Layer

Artist Layer有兩種型式： 基元(primitives) 和 容器(containers) 。基元主要是要處理我們在畫布上欲繪製的標準圖形對象，例如Line2D、Rectangle、Text、AxesImage等等，而容器則是要處理放置它們的位置，例如Figure, Subplot, and Axes。所以Artist Layer可以清楚知道圖形是如何由各子圖組成的，以及物體在給定的軸坐標系(Axes)中的相對位置。

Artist Layer有兩種型式： 和 。基元主要是要處理我們在畫布上欲繪製的標準圖形對象，例如Line2D、Rectangle、Text、AxesImage等等，而容器則是要處理放置它們的位置，例如Figure, Subplot, and Axes。所以Artist Layer可以清楚知道圖形是如何由各子圖組成的，以及物體在給定的軸坐標系(Axes)中的相對位置。 Scripting Layer

如果我們正在寫一個應用程式而來使用matplotlib，我們可能不會關心腳本層(Scripting Layer)，但這一層可以幫助我們簡化及加速與環境的互動，以方便快速建立圖形。前面所提Backend Layer著重於為工具包提供一個重要的接口，來呈現Artist Layer的基元(primitives)和容器(containers) ，但Scripting Layer卻是以用戶的角度來簡化與其他層一起工作的任務。而在本文章中的範例，所使用的腳本層就做pyplot。

上述說明了matplotlib就像個多層次的蛋糕一樣。有一個後端(Backend Layer)來處理實際的繪圖，而在他的上面則有一群藝術家(Artist Layer)描述著許多數據的排列方式，再根據腳本(Scripting Layer)實際上創建了這些藝術家並將它們一起編排起來表演。相信這樣的說明再配合後面的範例，將可讓初學者更了解其架構。

2.Plot Anatomy & Workflow

Plot Anatomy

我們將一張圖的架構解析如下，其中圖形(Figure)包含並管理圖中的許多元素，而主要架構則決定將圖形與行為分開。

Workflow

用matplotlib串建新圖時，可參考下列基本步驟及範例：

Step 1 ：Prepare Data

Step 2 ：Create Plot

Step 3 ：Plot

Step 4 ：Customize Plot

Step 5 ：Save Plot

Step 6 ：Show Plot

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5] # Step 1

y = [5, 10, 20, 35, 45] # Step 1

fig = plt.figure() # Step 2

ax = fig.add_subplot(111) # Step 3

plt.plot(x, y, color='blue', linewidth=2, marker='o') # Step 3&4

plt.xlim(1, 5.5)

plt.savefig('workflow.png') # Step 5

plt.show() # Step 6

根據上面步驟範例產生下面圖形。

Matplotlib Fundamentals

1.Prepare The Data

>>> import matplotlib.pyplot as plt # import matplotlib

>>> import numpy as np # import numpy

>>> x = np.linspace(0, 10, 100) # x在0到10之間取100個元素

>>> y = np.cos(x) # 將產生的x元素，代入cos()產生對應y值

>>> z = np.sin(x) # 將產生的x元素，代入sin()產生對應z值

>>> plt.plot(x, y)

[<matplotlib.lines.Line2D object at 0x000002896B067F28>]

>>> plt.show()

2.Create Plot

Graphs on common axes

範例：

>>> import matplotlib.pyplot as plt

>>> Taipei_HTemp = [16.1, 16.5, 18.5, 21.9, 25.2, 27.7, 29.6, 29.2, 27.4, 24.5, 21.5, 17.9]

>>> Taipei_LTemp = [13.9, 14.2, 15.8, 19.0, 22.3, 24.6, 26.3, 26.1, 24.8, 22.3, 19.3, 15.6]

>>> month = range(1, 13)

>>> plt.plot(month, Taipei_HTemp, 'red') # 讀出month及Taipei_HTemp的資料，產生紅色線

>>> plt.plot(month, Taipei_LTemp, 'blue') # 讀出month及Taipei_LTemp的資料，產生藍色線

>>> plt.xlabel('Month') # x軸的Label

>>> plt.title('Taipei High and Low Temperature') # 此圖的title

>>> plt.show()

axes()

語法：axes( [x, y, width, height] )

範例：

>>> import matplotlib.pyplot as plt

>>> Taipei_HTemp = [16.1, 16.5, 18.5, 21.9, 25.2, 27.7, 29.6, 29.2, 27.4, 24.5, 21.5, 17.9]

>>> Taipei_LTemp = [13.9, 14.2, 15.8, 19.0, 22.3, 24.6, 26.3, 26.1, 24.8, 22.3, 19.3, 15.6]

>>> month = range(1, 13)

>>> plt.axes([0.05,0.1,0.425,0.9])

>>> plt.plot(month, Taipei_HTemp, 'red')

>>> plt.xlabel('Month')

>>> plt.title('Taipei High Temperature')

>>> plt.axes([0.525,0.1,0.425,0.9])

>>> plt.plot(month, Taipei_LTemp, 'blue')

>>> plt.xlabel('Month')

>>> plt.title('Taipei Low Temperature')

>>> plt.show()

利用axes()的方法可以將資料分成兩張圖的方式呈現，並且可以分開控制其相關參數。雖然看起來左右圖形長得很像，但仔細觀察y軸刻度是不一樣的，未來教大家調整成一樣的刻度時就會看出明顯的差異。

subplot()

語法：subplot(nrows, ncols, nsubplot)

nrows：列數

ncols：行數

nsubplot：第n個子圖

如果nrows, ncols, nsubplot數字都在0~9之間的話，可以簡寫成如subplot(321)，表示為將子圖分成3列2行(共6個子圖)中的第1個。

>>> import matplotlib.pyplot as plt

>>> plt.subplot(321)

>>> plt.subplot(322)

>>> plt.subplot(312)

>>> plt.subplot(337)

>>> plt.subplot(338)

>>> plt.subplot(339)

>>> plt.show()

範例：

>>> import matplotlib.pyplot as plt

>>> Taipei_HTemp = [16.1, 16.5, 18.5, 21.9, 25.2, 27.7, 29.6, 29.2, 27.4, 24.5, 21.5, 17.9]

>>> Taipei_LTemp = [13.9, 14.2, 15.8, 19.0, 22.3, 24.6, 26.3, 26.1, 24.8, 22.3, 19.3, 15.6]

>>> month = range(1, 13)

>>> plt.subplot(2, 1, 1)

>>> plt.plot(month, Taipei_HTemp, 'red')

>>> plt.xlabel('Month')

>>> plt.title('Taipei High Temperature')

>>> plt.subplot(2, 1, 2)

>>> plt.plot(month, Taipei_LTemp, 'blue')

>>> plt.xlabel('Month')

>>> plt.title('Taipei Low Temperature')

>>> plt.tight_layout()

>>> plt.show()

3.Customize Plot

Basic Plot

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp)

>>> plt.show()

Color

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue')

>>> plt.show()

Marker

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue', marker='o')

>>> plt.show()

Linestyles

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue', marker='o', linestyle = '--')

>>> plt.show()

Labels and Title

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue', marker='o', linestyle = '--')

>>> plt.xlabel('Year', color = 'red')

>>> plt.ylabel('Temperature', color = 'red')

>>> plt.title('10-year Average Temperature', color = 'red')

>>> plt.show()

Multiple data

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> Taichung_temp = [23.5, 23.8, 23.7, 23.5, 23.6, 23.6, 23.8, 24.3, 24.2, 24.2]

>>> Kaohsiung_temp = [25.1, 25.4, 25.4, 24.9, 25.4, 25.5, 25.6, 26.1, 25.9, 26.3]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue', marker='o', linestyle = '--')

>>> plt.plot(year, Taichung_temp, color = 'orange', marker='o', linestyle = '-')

>>> plt.plot(year, Kaohsiung_temp, color = 'green', marker='.', linestyle = '-.')

>>> plt.xlabel('Year', color = 'red')

>>> plt.ylabel('Temperature', color = 'red')

>>> plt.title('10-year Average Temperature', color = 'red')

>>> plt.show()

Legends

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> Taichung_temp = [23.5, 23.8, 23.7, 23.5, 23.6, 23.6, 23.8, 24.3, 24.2, 24.2]

>>> Kaohsiung_temp = [25.1, 25.4, 25.4, 24.9, 25.4, 25.5, 25.6, 26.1, 25.9, 26.3]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue', marker='o', linestyle = '--’, label='Taipei')

>>> plt.plot(year, Taichung_temp, color = 'orange', marker='o', linestyle = '-', label='Taichung')

>>> plt.plot(year, Kaohsiung_temp, color = 'green', marker='.', linestyle = '-.’, label='Kaohsiung')

>>> plt.legend(loc = 'upper left')

>>> plt.xlabel('Year', color = 'red')

>>> plt.ylabel('Temperature', color = 'red')

>>> plt.title('10-year Average Temperature', color = 'red')

>>> plt.show()

Ticks

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> Taichung_temp = [23.5, 23.8, 23.7, 23.5, 23.6, 23.6, 23.8, 24.3, 24.2, 24.2]

>>> Kaohsiung_temp = [25.1, 25.4, 25.4, 24.9, 25.4, 25.5, 25.6, 26.1, 25.9, 26.3]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue', marker='o', linestyle = '--’, label='Taipei')

>>> plt.plot(year, Taichung_temp, color = 'orange', marker='o', linestyle = '-', label='Taichung')

>>> plt.plot(year, Kaohsiung_temp, color = 'green', marker='.', linestyle = '-.’, label='Kaohsiung')

>>> plt.legend(loc = 'upper left')

>>> plt.xlabel('Year', color = 'red')

>>> plt.ylabel('Temperature', color = 'red')

>>> plt.title('10-year Average Temperature', color = 'red’)

>>> plt.xticks([2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017], [97, 98, 99, 100, 101, 102, 103, 104, 105, 106])

>>> plt.show()

Limits

>>> import matplotlib.pyplot as plt

>>> Taipei_temp = [23.2, 23.4, 23.3, 22.7, 23.2, 23.4, 23.5, 23.8, 24, 23.9]

>>> Taichung_temp = [23.5, 23.8, 23.7, 23.5, 23.6, 23.6, 23.8, 24.3, 24.2, 24.2]

>>> Kaohsiung_temp = [25.1, 25.4, 25.4, 24.9, 25.4, 25.5, 25.6, 26.1, 25.9, 26.3]

>>> year = range(2008, 2018)

>>> plt.plot(year, Taipei_temp, color = 'blue', marker='o', linestyle = '--’, label='Taipei')

>>> plt.plot(year, Taichung_temp, color = 'orange', marker='o', linestyle = '-', label='Taichung')

>>> plt.plot(year, Kaohsiung_temp, color = 'green', marker='.', linestyle = '-.’, label='Kaohsiung’)

>>> plt.xlim(2005, 2018) # 調整x軸

>>> plt.ylim(20, 35) # 調整y軸

>>> plt.legend(loc = 'upper left')

>>> plt.xlabel('Year', color = 'red')

>>> plt.ylabel('Temperature', color = 'red')

>>> plt.title('10-year Average Temperature', color = 'red’)

>>> plt.xticks([2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017], [97, 98, 99, 100, 101, 102, 103, 104, 105, 106])

>>> plt.show()

4.Save Plot

可將建立後的圖形存成檔案格式，如下面範例。

Save figures

>>> plt.savefig('test1.png')

Save transparent figures