matplotlib - matplotlib 教程


Pyplot 教程

關於pylot接口的介紹。

matplotlib 教程

這個圖庫包含了使用Matplotlib可以做的許多事情的示例。可以點擊任何圖像,以查看完整的圖像和源代碼。

有關更短的示例,請參見示例頁。你還可以在我們的用戶指南中找到外部資源常見問題解答

matplotlib 入門

這些教程介紹了使用Matplotlib創建可視化效果的基礎知識,以及有效使用該包的一些最佳實踐。

使用指南

本教程介紹一些基本的使用模式和最佳實踐,以幫助您開始使用Matplotlib。

一般概念

matplotlib有一個廣泛的代碼庫,對於許多新用戶來說,這個代碼庫可能會讓人望而生畏。然而,大多數Matplotlib可以用相當簡單的概念框架和幾個要點的知識來理解。

打印需要在一系列級別上執行操作,從最一般的級別(例如“輪廓此二維陣列”)到最具體的級別(例如“將此屏幕像素塗成紅色”)。繪圖軟件包的目的是通過所有必要的控制,幫助您盡可能輕松地可視化您的數據-也就是說,在大多數情況下使用相對較高級別的命令,並且在需要時仍然能夠使用低級別命令。

因此,matplotlib中的所有內容都是按照層次結構組織的。層次結構的頂部是matplotlib“狀態機環境”,它是由matplotlib.pylot模塊提供的。在這個級別上,使用簡單的函數來添加打印元素(線、圖像、文本等)。到當前地物中的當前軸。

注意:Pyplot的狀態機環境的行為類似於MATLAB,並且對於具有MATLAB經驗的用戶來說應該是最熟悉的。

層次結構中的下一級是面向對象的接口的第一級,其中pyplot僅用於少數功能,例如圖形創建,並且用戶顯式創建並跟蹤圖形和軸對象。 在此級別,用戶使用pyplot來創建圖形,並且通過這些圖形,可以創建一個或多個軸對象。 然后,這些軸對象用於大多數繪圖操作。

對於更多的控制 - 這對於在GUI應用程序中嵌入matplotlib圖表這一點至關重要 - 可以完全刪除pyplot級別,從而留下純粹面向對象的方法。

# 導入matplotlib模塊
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

一個圖的一部分

Figure

該圖記錄了所有子軸,一些 “特殊” 的藝術家(標題,圖形圖例等)和畫布。(不要過於擔心畫布,它是至關重要的,因為它實際上是繪圖的對象,以獲得你繪制的圖像,但作為用戶它或多或少是你不可見的)。一個數字可以有任意數量的Axes,但是有用的應該至少有一個。
創建一個圖像的最簡單方法是使用pylot:

# 沒有坐標軸的空圖形
fig = plt.figure()

# 為圖形添加一個標題
fig.suptitle('No axes on this figure')

# 帶有2x2坐標軸網格的圖形
fig, ax_lst = plt.subplots(2, 2)

png

Axes對象

這就是你想象中的“一幅圖”,它是具有數據空間的圖像區域。給定的圖形可以包含許多軸,但給定的Axes對象只能在一個圖中。 Axes包含兩個(或3D的三個)Axis對象(注意Axes和Axis之間的差異),它們負責數據限制(數據限制也可以通過 set_xlim()set_ylim() 來設置Axes方法)。每個Axes都有一個標題(通過 set_title() 設置),一個x標簽(通過 set_xlabel() 設置)和一個通過 set_ylabel() 設置的y標簽。

Axis 類及其成員函數是使用 OO 接口的主要入口點。

Axis對象

這些是類似數字的對象。它們負責設置圖形限制並生成刻度線(軸上的標記)和ticklabels(標記刻度線的字符串)。刻度線的位置由Locator對象確定,ticklabel字符串由Formatter格式化。正確的定位器和格式化器的組合可以非常精確地控制刻度位置和標簽。

Artist對象

基本上你在圖上看到的一切都是藝術家(Artist)對象(甚至是圖,軸和軸對象)。這包括Text對象,Line2D對象,集合對象,Patch對象......(現在你明白了)。渲染圖形時,所有藝術家都被繪制到畫布(canvas)上。大多數藝術家(Artist)都與軸有關; 這樣的藝術家(Artist)不能被多個軸共享,也不能從一個軸移動到另一個軸。

繪制函數的輸入類型

所有繪圖函數都需要np.array或np.ma.masked_array對象作為輸入類型。如果是 “類數組(array-like)” 對象(如pandas數據對象和np.matrix)可能會或可能不會按預期工作。最好在繪圖之前將它們轉換為np.array對象。

例如,要轉換pandas.DataFrame

a = pd.DataFrame(np.random.rand(4,5), columns = list('abcde'))
a_asndarray = a.values

以及轉換np.matrix

b = np.matrix([[1,2],[3,4]])
b_asarray = np.asarray(b)

Matplotlib,pyplot和pylab:它們之間有什么關系?

Matplotlib是整個包; matplotlib.pyplot 是 matplotlib中的一個模塊; 和pylab是一個與 matplotlib 一起安裝的模塊。

Pyplot為底層面向對象的繪圖庫提供狀態機接口。 狀態機隱式地自動創建圖形和軸以實現所需的圖形。例如:

x = np.linspace(0, 2, 100)

#創建圖形和軸,實現繪圖
plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')

#x/y軸標簽
plt.xlabel('x label')
plt.ylabel('y label')

#表名
plt.title("Simple Plot")

plt.legend()

plt.show()

png

第一次調用 plt.plot 將自動創建必要的圖形和軸以實現所需的繪圖。隨后對plt.plot的調用會重新使用當前軸,並且每次都會添加另一行。設置標題,圖例和軸標簽還會自動使用當前軸並設置標題,創建圖例並分別標記軸。

pylab是一個便利模塊,它在單個名稱空間中批量導入 matplotlib.pyplot(用於繪圖)和numpy一樣(用於數學和使用數組)。不過不推薦使用pylab,並且由於命名空間污染而強烈建議不要使用它。請改用pyplot。

對於非交互式繪圖,建議使用pyplot創建圖形,然后使用OO界面進行繪圖。

代碼風格

查看此文檔和示例時,您將找到不同的代碼樣式和使用模式。這些風格完全沒有問題,各有利弊。幾乎所有示例都可以轉換為另一種樣式並實現相同的結果。唯一需要注意的是避免為自己的代碼混合了別的代碼風格,盡量保持風格的統一。

注意:matplotlib的開發人員必須遵循特定的編程風格和指導原則。請參見Matplotlib開發人員手冊

在不同的風格中,有兩種是官方支持的。因此,這些是使用matplotlib的首選方法。

對於pyplot樣式,腳本頂部的通常導入:

import matplotlib.pyplot as plt
import numpy as np

然后調用一次,例如,np.arange,np.zeros,np.pi,plt.figure,plt.plot,plt.show等。使用pyplot接口創建圖像,然后使用對象方法:
然后使用對象方法:

plt.figure(figsize = (10, 6))
x = np.arange(0, 10, 0.2)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()

png

那么,為什么所有都是額外的類型而不是MATLAB樣式(依賴於全局狀態和平面名稱空間)呢?對於像這個例子這樣非常簡單的事情,唯一的好處是學術性的:更冗長的風格更明確,更清楚地說明事物從何而來,以及正在發生的事情。對於更復雜的應用程序,這種明確性和明確性變得越來越有價值,而更豐富和更完整的面向對象接口可能會使程序更易於編寫和維護。

def my_plotter(ax, data1, data2, param_dict):
    """
    用來制作圖表的輔助函數
    參數
    ----------
    ax:Axes
        要畫的坐標軸
    data1:數組
        x數據
    data2:數組
        y數據
    param_dict: dict類型
        要傳遞給ax.plot的kwargs字典
    Returns
    -------
    list:
        list of artists added
    """
    out = ax.plot(data1, data2, **param_dict)
    return out

# which you would then use as:
plt.figure(figsize = (10, 6))
data1, data2, data3, data4 = np.random.randn(4, 100)
fig, ax = plt.subplots(1, 1)
my_plotter(ax, data1, data2, {'marker': 'x'})

png

或者如果你想有兩個小子圖:

# 創建帶有1x2坐標軸網格的圖形
fig, (ax1, ax2) = plt.subplots(1, 2)


my_plotter(ax1, data1, data2, {'marker': 'x'})


my_plotter(ax2, data3, data4, {'marker': 'o'})

png

同樣,對於這些簡單的例子來說,這種風格看起來有點過頭了,但是一旦圖形變得稍微復雜一些,就會有回報。

后端(Backends)

什么是后端?

網站和郵件列表中的許多文檔都提到了“后端(Backends)”,許多新用戶對這個術語感到困惑。matplotlib針對許多不同的用例和輸出格式。有些人在python shell中以交互方式使用matplotlib,並在鍵入命令時彈出繪圖窗口。有些人運行Jupyter筆記本並繪制內聯圖以進行快速數據分析。其他人將matplotlib嵌入到圖形用戶界面(如wxpython或pygtk)中以構建豐富的應用程序。有些人在批處理腳本中使用matplotlib從數值模擬生成postscript圖像,還有一些人運行Web應用程序服務器來動態提供圖形。

為了支持所有這些用例,matplotlib可以針對不同的輸出,並且這些功能中的每一個都稱為后端(Backends); “前端(frontend)”是面向用戶的代碼,即繪圖代碼,而“后端(Backends)”完成幕后的所有艱苦工作以制作圖形。 有兩種類型的后端:用戶界面后端(用於pygtk,wxpython,tkinter,qt4或macosx;也稱為“交互式后端”)和硬拷貝后端來制作圖像文件(PNG,SVG,PDF,PS; 也被稱為“非交互式后端”)。

配置后端有四種方法。如果它們彼此沖突,將使用以下列表中最后提到的方法,例如,調用 use() 將覆蓋 matplotlibrc 中的設置。

matplotlibrc文件中的后端參數(請參閱[使用樣式表和rcParams自定義Matplotlib](https://matplotlib.org/tutorials/introductory/customizing.html)):
backend : WXAgg   #使用帶有反紋理(agg)呈現的wxpython
在Unix系統上,為當前shell或單個腳本設置[MPLBACKEND](https://matplotlib.org/faq/environment_variables_faq.html#envvar-MPLBACKEND)環境變量:
> export MPLBACKEND=module://my_backend
> python simple_plot.py

> MPLBACKEND="module://my_backend" python simple_plot.py

在Windows上,只有前者是可用的:

> set MPLBACKEND=module://my_backend
> python simple_plot.py

設置此環境變量將覆蓋任何 matplotlibrc 中的后端參數,即使當前工作目錄中存在matplotlibrc也是如此。 因此,全局設置MPLBACKEND ,例如 在.bashrc 或 .profile 中,不鼓勵它,因為它可能導致反常的行為。
如果您的腳本依賴於特定的后端,則可以使用 use() 函數:

import matplotlib

# 默認情況下生成postscript輸出
matplotlib.use('PS')   

如果使用 use() 函數,則必須在輸入 matplotlib.pyplot 之前完成此操作。導入 pyplot 后調用 use() 將不起作用。如果用戶希望使用不同的后端,則使用 use() 將需要更改代碼。因此,除非絕對必要,否則應避免顯式調用 use()

注意:后端名稱規范不區分大小寫;例如,‘GTK3Agg’ 和 ‘gtk3agg’ 是等效的。

通過典型的方式安裝matplotlib,例如:從二進制安裝程序或Linux發行包安裝的話,可以設置好一個默認的后端,允許交互式工作和從腳本繪圖,輸出到屏幕和/或文件,所以至少一開始的時候你不需要使用上面給出的任何方法。

但是,如果您想編寫圖形用戶界面或Web應用程序服務器(Web應用程序服務器中的Matplotlib),或者需要更好地了解正在發生的事情,請繼續閱讀。為了使圖形用戶界面可以更加自定義,matplotlib將畫布(繪圖所在的位置)中的渲染器(實際繪制的東西)的概念分開。用戶界面的規范渲染器是Agg,它使用 Anti-Grain Geometry C++庫來制作圖形的光柵(像素)圖像。除macosx之外的所有用戶界面都可以與agg渲染一起使用,例如WXAgg,GTK3Agg,QT4Agg,QT5Agg,TkAgg。此外,一些用戶界面支持其他渲染引擎。 例如,使用GTK + 3,您還可以選擇Cairo渲染(后端GTK3Cairo)。

對於渲染引擎,還可以區分矢量(vector)或光柵(raster)渲染器。矢量圖形語言發出繪圖命令,例如“從此點到此點繪制線”,因此無標度,並且柵格后端生成線的像素表示,其精度取決於DPI設置。

下面是matplotlib渲染器的摘要(每個渲染器都有一個同名的后端;它們是非交互式后端,能夠寫入文件):

渲染格式 文件類型 描述
AGG png raster graphics -- 使用反紋理幾何(Anti-Grain Geometry)引擎的高質量圖像。
PS ps eps vector graphics -- Postscript output
PDF pdf vector graphics -- Portable Document Format
SVG svg vector graphics -- Scalable Vector Graphics
Cairo png ps pdf svg raster graphics 和 vector graphics -- 使用 Cairo圖形庫(Cairo graphics)庫

以下是支持的用戶界面和渲染器組合; 這些是交互式后端,能夠顯示到屏幕並使用上表中的適當渲染器寫入文件:

渲染格式 文件類型
Qt5Agg 在Qt5畫布中進行Agg渲染(需要PyQt5)。可以在IPython中使用 %matplotlib qt5 激活此后端。
ipympl 嵌入在Jupyter小部件中的Agg渲染。(需要ipympl)。這個后端可以在帶有%matplotlib ipympl 的Jupyter筆記本中啟用。
GTK3Agg Agg渲染到GTK 3.x畫布(需要PyGObject,pycairo或cairocffi)。 可以使用%matplotlib gtk3 在 IPython中激活此后端。
macosx 將AGG渲染到OSX中的Cocoa畫布中。可以在IPython中使用 %matplotlib OSX 激活此后端。
TkAgg Agg渲染到Tk畫布(需要TkInter)。可以使用 %matplotlib tk 在IPython中激活此后端。
nbAgg 在經典的Jupyter筆記本中嵌入一個交互式界面。 可以通過%matplotlib 筆記本 在Jupyter筆記本中啟用此后端。
WebAgg show() 將啟動一個帶有交互式圖形的 tornado 服務。
GTK3Cairo 在GTK 3.x畫布上呈現cairo(需要PyGObject 和 pycairo 或 cairocffi )。
Qt4Agg Agg渲染到 Qt4 畫布(需要 PyQt4 或pyside)。可以使用 %matplotlib qt4 在IPython中激活此后端。
WXAgg Agg渲染到 wxWidgets 畫布(需要wxPython 4)。可以使用 %matplotlib wx 在IPython中激活此后端。

ipympl

Jupyter小部件生態系統的移動速度太快,無法直接在Matplotlib中支持。安裝ipympl

pip install ipympl
jupyter nbextension enable --py --sys-prefix ipympl

# 或者
conda install ipympl -c conda-forge

請參閱 jupyter-matplotlib 了解更多細節。

GTK 和 Cairo

GTK3 后端 (包括 GTK3Agg 和 GTK3Cairo) 依賴於 Cairo (pycairo>=1.11.0 或 cairocffi).

如何選擇PyQt4或PySide?

QT_API環境變量可以設置為 pyqt 或 pyside,分別使用 PyQt4 或 PySide。

由於要使用的綁定的默認值是PyQt4,matplotlib 首先嘗試導入它,如果導入失敗,它會嘗試導入 PySide。

什么是交互模式?###

使用交互式后端(請參閱什么是后端?)允許但本身並不需要或確保繪制到屏幕上。是否以及何時繪制到屏幕,以及在屏幕上繪制繪圖后是否繼續腳本或shell會話取決於調用的函數和方法,以及確定matplotlib是否處於“交互模式”的狀態變量”。默認的布爾值由matplotlibrc文件設置,並且可以像任何其他配置參數一樣進行自定義(請參閱使用樣式表和rcParams自定義Matplotlib)。它也可以通過matplotlib.interactive() 設置,並且可以通過matplotlib.is_interactive() 查詢其值。無論是在腳本還是在shell中,在繪圖命令流的中間打開和關閉交互模式很少需要並且可能令人困惑,因此在下文中我們將假設所有繪圖都是以交互模式打開或關閉。

注意:與交互性相關的主要更改,特別是show()的角色和行為,在向matplotlib 1.0版的過渡中進行了更改,並在1.0.1中修復了錯誤。這里我們描述主要交互式后端的1.0.1版行為,但MacOSX除外。

交互模式也可以通過matplotlib.pyplot.ion()打開,並通過matplotlib.pyplot.ioff()關閉。

注意:交互模式在ipython和普通的python shell中使用合適的后端,但它在IDLE IDE中不起作用。如果默認后端不支持交互性,則通過“可以使用什么是后端?”這個話題中討論的任何方法顯式激活交互式后端。

交互例子

從普通的python提示符,或者在沒有選項的情況下調用ipython之后,試試這個:

import matplotlib.pyplot as plt
plt.ion()
plt.plot([1.6, 2.7])
[<matplotlib.lines.Line2D at 0x20712cf1828>]

png

假設您運行的是1.0.1或更高版本,並且默認情況下安裝並選擇了交互式后端,您應該看到一個圖,並且您的終端提示也應該是活動的; 您可以鍵入其他命令,例如:

plt.title("interactive test")
plt.xlabel("index")
Text(0.5, 0, 'index')

png

然后你會看到每一行后都要更新繪圖。從版本1.5開始,通過其他方式修改繪圖也應該自動更新大多數后端的顯示。獲取對Axes實例的引用,並調用該實例的方法:

ax = plt.gca()
ax.plot([3.1, 2.2])
[<matplotlib.lines.Line2D at 0x20712a740f0>]

png

如果你使用的是某些后端(如macosx)或舊版本的matplotlib,則可能無法立即將新行添加到繪圖中。在這種情況下,您需要顯式調用draw() 以更新繪圖:

plt.draw()
<Figure size 432x288 with 0 Axes>

非交互式示例

像上一個示例中一樣開始一個新會話,但現在關閉交互模式:

import matplotlib.pyplot as plt
plt.ioff()
plt.plot([1.6, 2.7])
[<matplotlib.lines.Line2D at 0x20712a9afd0>]

png

什么都沒發生 - 或者至少沒有任何東西出現在屏幕上(除非你使用macosx后端,這是異常的)。要顯示繪圖,您需要執行以下操作:

plt.show()

現在你看到圖像,但你的終端命令行沒有響應; show() 命令會阻止其他命令的輸入,直到您手動終止繪圖窗口。

被迫使用阻塞功能?這有什么用,假設您需要一個腳本,將文件內容繪制到屏幕上。您想查看該圖,然后結束腳本。如果沒有一些阻塞命令(如show()),腳本會閃現圖像,然后立即結束,屏幕上不顯示任何內容。

此外,非交互模式會將所有圖形延遲到調用show();這比每次在腳本中添加新功能時重新繪制打印更有效。

在版本1.0之前,show()通常不能在單個腳本中調用多次(盡管有時可以不受限制);對於版本1.0.1及更高版本,此限制已解除,因此可以編寫如下腳本:

import numpy as np
import matplotlib.pyplot as plt

plt.ioff()
for i in range(3):
    plt.plot(np.random.rand(10))
    plt.show()

png

這就形成了三個陰謀,一次一個。即。第一個地塊關閉后,將顯示第二個地塊。

摘要

在交互模式下,pyplot功能會自動繪制到屏幕上。

交互式繪制時,如果除了pyplot函數之外還使用對象方法調用,則只要想要刷新繪圖,就調用draw()

在要生成一個或多個圖形的腳本中使用非交互模式,並在結束或生成一組新圖形之前顯示它們。在這種情況下,使用show()顯示圖形並阻止執行,直到您手動銷毀它們。

性能

無論是以交互模式探索數據還是以編程方式保存大量繪圖,渲染性能都可能成為您管道中的一個痛苦瓶頸。Matplotlib提供了幾種方法來大大減少渲染時間,但代價是繪圖外觀略有變化(達到可設置的容差)。可用於縮短渲染時間的方法取決於正在創建的繪圖類型。

線段簡化

對於具有直線段的打印(例如,典型的直線打印、多邊形輪廓等),渲染性能可以由matplotLibrc文件中的path.Simplify和path.Simplify_Threshold參數控制(有關matplotlib文件的詳細信息,請參見使用樣式表和rcParams自定義Matplotlib)。Simplify參數是一個布爾值,用於指示是否簡化了直線段。path.Simplify_Threshold參數控制簡化線段的程度;閾值越高,渲染速度越快。

以下腳本將首先顯示數據而不進行任何簡化,然后簡化顯示相同的數據。 嘗試與它們互動:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

# 設置並創建要繪圖的數據
y = np.random.rand(100000)
y[50000:] *= 2
y[np.logspace(1, np.log10(50000), 400).astype(int)] = -1
mpl.rcParams['path.simplify'] = True

mpl.rcParams['path.simplify_threshold'] = 0.0
plt.plot(y)
plt.show()

mpl.rcParams['path.simplify_threshold'] = 1.0
plt.plot(y)
plt.show()

png

Matplotlib目前默認為1/9的保守簡化閾值。如果要更改默認設置以使用其他值,可以更改matplotlibrc文件。或者,您可以為交互式繪圖(具有最大簡化)創建新樣式,並為出版質量繪圖創建另一種樣式(最小化簡化)並根據需要激活它們。有關如何執行這些操作的說明,請參閱使用樣式表和rcParams自定義Matplotlib

簡化通過將線段迭代地合並為單個矢量直到下一個線段與矢量的垂直距離(在顯示坐標空間中測量)大於 path.simplify_threshold 參數來工作。

注意:與版本細分如何簡化相關的更改在版本2.1中進行。 2.1之前的這些參數仍將改善渲染時間,但2.1版及更高版本的某些類型數據的渲染時間將大大改善。

標記簡化

標記也可以簡化,盡管不如線段強大。標記簡化僅適用於Line2D對象(通過市場營銷屬性)。無論在哪里傳遞Line2D構造參數,例如matplotlib.pyplot.plot()matplotlib.axes.Axes.plot(),都可以使用markevery參數:

plt.plot(x, y, markevery=10)

png

市場營銷論證允許天真的子采樣,或嘗試均勻間隔(沿x軸)采樣。 有關更多信息,請參閱Markevery演示。

將線分割成較小的塊

如果您正在使用Agg后端(請參閱什么是后端?),那么您可以使用 agg.path.chunksize rc參數。這允許您指定塊大小,並且任何具有大於該多個頂點的行將被分割成多行,每行不超過 agg.path.chunksize 許多頂點。(除非agg.path.chunksize為零,在這種情況下沒有分塊。)對於某種類型的數據,將線條分成合理的大小可以大大減少渲染時間。

以下腳本將首先顯示沒有任何塊大小限制的數據,然后顯示塊大小為10,000的相同數據。當數字很大時,可以最好地看到差異,嘗試最大化GUI然后與它們進行交互:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['path.simplify_threshold'] = 1.0

# Setup, and create the data to plot
y = np.random.rand(100000)
y[50000:] *= 2
y[np.logspace(1,np.log10(50000), 400).astype(int)] = -1
mpl.rcParams['path.simplify'] = True

mpl.rcParams['agg.path.chunksize'] = 0
plt.plot(y)
plt.show()

mpl.rcParams['agg.path.chunksize'] = 10000
plt.plot(y)
plt.show()

png

圖例

軸的默認圖例行為嘗試查找覆蓋最少數據點的位置(loc ='best')。 如果有大量數據點,這可能是非常昂貴的計算。 在這種情況下,您可能希望提供特定位置。

使用快速的風格

快速樣式可用於自動將簡化和分塊參數設置為合理的設置,以加快繪制大量數據的速度。它可以通過運行簡單地使用:

import matplotlib.style as mplstyle
mplstyle.use('fast')

它的重量非常輕,因此它可以很好地與其他風格配合使用,只需確保最后應用快速樣式,以便其他樣式不會覆蓋設置:

mplstyle.use(['dark_background', 'ggplot', 'fast'])


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM