天天看點

Matplotlib 應用程式接口(APIs)

作者:洪流82212991

Matplotlib 有兩種主要的應用程式接口,或者說叫使用風格:

  • 一種是顯式調用“Axes”接口,使用Figure或Axes對象的方法來建立Artists,并一步步建立符合你要求的圖象。這種也叫面向對象程式設計風格。
  • 一咱是隐式調用“pyplot”接口,它用于跟蹤最新建立的Figure和Axes,并自動添加它認為使用者需要的Artists。 另外,一些下遊的庫,比如pandas和array等,在它們自身的資料集中整合了提供了一個 plot 方法,使用者可以直接調用data.plot()。 這兩種風格的接口讓人看起來有些迷糊,特别是在網絡上有些例子一會兒用這個,一會兒用這個,實作的效果還都差不多。是以這裡我們試着指出“bylot”和它的下遊接口是如保與顯式的“Axes”接口相關聯的。

本地的Matplotlib接口

顯式“Axes”接口

  • Axes接口是Matplotlib的基礎實作方式,很多自定義繪圖和微調動作都是這個級别上進行的。 這個接口使用subplots方法執行個體化了一個Figure對象(如下面的fig)并以此來建立一個或多個Axes對象(如下面的ax),然後使用Axes對象的繪圖指令(plot函數)來顯示圖像。 如:

import matplotlib.pyplot as plt

fig = plt.figure() #建立畫布

ax = fig.subplots() # 建立坐标系

ax.plot([1,2,3,4],[4,3,2,1]) #繪圖

[<matplotlib.lines.Line2D at 0xffff812214a8>]

Matplotlib 應用程式接口(APIs)

我們叫它“顯式”是因為每個對象都是被顯式調用的。并且用于生成下一個對象。保留對對象的引用可以保持一定的靈活性,并且允許我們在生成對象之後,顯示對象之前對對象進行自定義。

隐式的“pyplot”接口

pylot子產品隐藏了大多數的Axes繪圖方式,但給出了與上個例子等效的圖形,裡面的Figure 和Axes由子產品自動處理了。

import matplotlib.pyplot as plt

plt.plot([1,2,3,4],[4,3,2,1])

[<matplotlib.lines.Line2D at 0xffff811a6cf8>]

Matplotlib 應用程式接口(APIs)

這種方式很友善,特别是在進行互動式工作或編簡單的腳本的時候。目前的Figure可以用gcf()函數來進行記錄,目前的Axes用gca()來記錄。pyplot子產品給使用者保留一個Figures的清單,每個Figure保留了一個Axes的清單:

import matplotlib.pyplot as plt

plt.subplot(1,2,1)

plt.plot([1,2,3],[0,5,2])

plt.subplot(1,2,2)

plt.plot([3,2,1],[0,5,2])

[<matplotlib.lines.Line2D at 0xffff8112ca90>]

Matplotlib 應用程式接口(APIs)

這相當于

import matplotlib.pyplot as plt

plt.subplot(1,2,1)

ax = plt.gca()

ax.plot([1,2,3],[0,5,2])

plt.subplot(1,2,2)

ax = plt.gca()

ax.plot([3,2,1],[0,5,2])

[<matplotlib.lines.Line2D at 0xffff810497b8>]

Matplotlib 應用程式接口(APIs)

如果用顯式接口,它是這樣的。

import matplotlib.pyplot as plt

fig,axs = plt.subplots(1,2)

axs[0].plot([1,2,3],[0,5,2])

axs[1].plot([3,2,1],[0,5,2])

[<matplotlib.lines.Line2D at 0xffff80f0a438>]

Matplotlib 應用程式接口(APIs)

為什麼用顯式調用? 當你碰到不得不對沒有使用plt.gca()進行标記的舊軸上進行操作時,會發生什麼?一種簡單的方法是再次用相同的參數調用subplot,但這樣很快就會讓代碼變得臃腫,不夠優雅;另一種是檢查Figure對象的Axes對象清單,但這樣經常會出錯,因為很多其他的色帶也是Axes對象,最好的解決方案也許是給每一個Axes填加一個句柄(一個變量名),但這樣搞的話,就又不如在開始的時候就建立所有的Axes對象來得友善了。來一個例子看看:

import matplotlib.pyplot as plt

plt.subplot(1,2,1)

plt.plot([1,2,3],[0,5,2])

plt.subplot(1,2,2)

plt.plot([3,2,1],[0,5,2])

plt.suptitle('Implicit interface:re-call subplot')

for i in range(1,3):

plt.subplot(1,2,i)

plt.xlabel('Boo')

Matplotlib 應用程式接口(APIs)

import matplotlib.pyplot as plt

axs = []

ax1 = plt.subplot(1,2,1)

# axs += [ax1]

axs.append(ax1)

plt.plot([1,2,3],[0,5,2])

ax2 = plt.subplot(1,2,2)

# axs += [ax2]

axs.append(ax2)

plt.plot([3,2,1],[0,5,2])

plt.suptitle('Implicit Interface: save handles')

for i in range(2):

plt.sca(axs[i])

plt.xlabel('Boo')

print(axs)

[<AxesSubplot:xlabel='Boo'>, <AxesSubplot:xlabel='Boo'>]

Matplotlib 應用程式接口(APIs)

建議的方式是在開始時就顯式聲明

import matplotlib.pyplot as plt

fig,axs = plt.subplots(1,2)

axs[0].plot([1,2,3],[0,5,2])

axs[1].plot([3,2,1],[0,5,2])

fig.suptitle('Explicit Interface')

for i in range(2):

axs[i].set_xlabel('Boo')

Matplotlib 應用程式接口(APIs)

第三方庫的資料對象接口

一些第三方庫已經實作對其資料進行繪圖,比如pandas和array都實作了data.plot()方法,下遊庫可以實作一個簡單的資料容器,該容器将x和y資料存儲在一起,然後實作繪圖方法:

import matplotlib.pyplot as plt

class DataContainer:

def __init__(self,x,y) :

self._x = x

self._y = y

def plot(self,ax = None,**kwargs):

if ax is None:

ax = plt.gca()

ax.plot(self._x,self._y,**kwargs)

ax.set_title('Plotted from DataClass!')

return ax

data = DataContainer([0,1,2,3],[0,2,5,3])

data.plot()

<AxesSubplot:title={'center':'Plotted from DataClass!'}>

Matplotlib 應用程式接口(APIs)

是以,第三方庫可以向使用者隐藏所有的細節,并可以根據資料類型進行可視化,并且通常具有良好的标簽、顔色圖選擇和其他友善的功能。

然而,在上述内容中,我們可能不喜歡庫提供的标題。幸運的是,它們從plot()方法中傳回了Axes對象,并且定義了明确的Axes接口,我們可以調用:ax.set_title(“My title”)來定制标題。

許多庫還允許其plot方法接受可選的ax參數。這允許我們在Axes中放置可視化對象并做一些自定義的設定。

總結一下

總的來說,明确了解的“Axes”接口非常有用,因為它是最靈活的對象,并且是其他接口的基礎。使用者通常可以知道如何下拉到顯式接口并對底層對象進行操作。雖然顯式接口的設定可能會更加冗長,但複雜的繪圖通常會比嘗試使用隐式“pyplot”接口更簡單。

類似地,合作夥伴的第三方庫提供的聲明性接口使用“Axes”接口可通路的對象,并經常将這些對象作為參數接受或從方法中傳遞回來。通常需要使用顯式的“Axes”接口來執行預設可視化的自定義設定,或者将資料解壓縮到NumPy數組中并直接傳遞到Matplotlib。

附錄:帶資料結構的“Axes”接口

大多數的Axes方法允許另一種API 即通過将資料對象通過字元串的方式傳遞進去。如

import matplotlib.pyplot as plt

data = {'xdat':[0,1,2,3],'ydat':[3,2,1,0]}

fig,ax = plt.subplots(figsize=(2,2))

ax.plot('xdat','ydat',data=data)

[<matplotlib.lines.Line2D at 0xffff806f6358>]

Matplotlib 應用程式接口(APIs)

附錄:“palabra”接口

還有一個接口非常不受歡迎,那就是通過matplotlib.pyplot import*來實作。這允許使用者簡單地調用plot(x,y)。雖然友善,但如果使用者無意中将變量命名為與pyplot方法相同的名稱,這可能會導緻明顯的問題。

繼續閱讀