Matplotlib繪圖生命週期


本教學旨在使用Matplotlib顯示單個視覺化的開始,中間和結尾。我們將從一些原始資料開始,最後儲存一個自定義視覺化圖形。在此過程中,我們將嘗試使用Matplotlib突出一些簡潔的功能和最佳實踐。

物件導向的API與Pyplot

Matplotlib有兩個介面。第一個是物件導向(OO)介面。在這種情況下,我們利用axes.Axes的範例來渲染圖形範例的視覺化。

第二種是基於MATLAB並使用基於狀態的介面,它封裝在pyplot模組中。請參閱pyplot教學,以深入了解pyplot介面。

大多數術語都很簡單,但要記住的主要是:

  • Figure是可能包含1個或更多軸的最終影象。
  • Axes代表一個單獨的圖(不要將其與「axis」這個詞混淆,後者指的是圖的x/y軸)。

直接呼叫從Axes進行繪圖的方法,這使我們在客製化繪圖方面具有更大的靈活性和強大功能。

注意 - 通常,嘗試在pyplot介面上使用物件導向的介面。

下面資料它包含許多公司的銷售資訊。

# sphinx_gallery_thumbnail_number = 10
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

data = {'Barton LLC': 109438.50,
        'Frami, Hills and Schmidt': 103569.59,
        'Fritsch, Russel and Anderson': 112214.71,
        'Jerde-Hilpert': 112591.43,
        'Keeling LLC': 100934.30,
        'Koepp Ltd': 103660.54,
        'Kulas Inc': 137351.96,
        'Trantow-Barrows': 123381.38,
        'White-Trantow': 135841.99,
        'Will LLC': 104437.60}
group_data = list(data.values())
group_names = list(data.keys())
group_mean = np.mean(group_data)

這些資料自然視覺化為條形圖,每組一個條形圖。要使用物件導向的方法執行此操作,我們首先生成figure.Figureaxes.Axes的範例。Figure就像一個畫布,Axes是畫布的一部分,下面我們將在它上面進行特定的視覺化。

fig, ax = plt.subplots()

現在有了一個Axes範例,然後就可以在它上面進行繪圖。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)

Axes實例

控制樣式

Matplotlib中有許多樣式可根據需要客製化視覺化。要檢視樣式列表,可以使用pyplot.style

print(plt.style.available)

輸出結果如下 -

['seaborn-ticks', 'ggplot', 'dark_background', 'bmh', 'seaborn-poster', 'seaborn-notebook', 'fast', 'seaborn', 'classic', 'Solarize_Light2', 'seaborn-dark', 'seaborn-pastel', 'seaborn-muted', '_classic_test', 'seaborn-paper', 'seaborn-colorblind', 'seaborn-bright', 'seaborn-talk', 'seaborn-dark-palette', 'tableau-colorblind10', 'seaborn-darkgrid', 'seaborn-whitegrid', 'fivethirtyeight', 'grayscale', 'seaborn-white', 'seaborn-deep']

可以使用以下內容啟用樣式:

plt.style.use('fivethirtyeight')

現在重新製作上面的繪圖,看看它輸出的樣子:

fig, ax = plt.subplots()
ax.barh(group_names, group_data)

樣式控制很多東西,比如顏色,線寬,背景等。

自定義繪圖

現在已經得到了一個想要的一般外觀的繪圖,下面對它進行微調,以便它可以列印出來。首先旋轉x軸上的標籤,使它們更清晰地顯示出來。可以使用axes.Axes.get_xticklabels()方法存取這些標籤:

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()

旋轉`x`軸上的標籤

如果想一次設定多個項的屬性,那麼可使用pyplot.setp()函式。它將獲取Matplotlib物件的列表(或許多列表),並嘗試設定每個物件的一些樣式元素。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

設置對象的樣式元素

看起來這樣會切斷底部的一些標籤。可以告訴Matplotlib自動建立的圖中的元素騰出空間。為此,設定rcParamsautolayout值。

plt.rcParams.update({'figure.autolayout': True})

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

autolayout值

接下來,為繪圖新增標籤。要使用OO介面執行此操作,可以使用axes.Axes.set()方法設定此Axes物件的屬性。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')

設置Axes對象的屬性

還可以使用pyplot.subplots()函式調整此圖的大小。可以用figsize kwarg做到這一點。

雖然NumPy中的索引遵循形式(行,列),但figsize kwarg遵循形式(寬度,高度)。它遵循視覺化中的慣例,遺憾的是它們與線性代數的慣例不同。

fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')

慣例

對於標籤,可以使用ticker.FuncFormatter類以函式的形式指定自定義格式。下面將定義一個以整數作為輸入的函式,並返回一個字串作為輸出。

def currency(x, pos):
    """The two args are the value and tick position"""
    if x >= 1e6:
        s = '${:1.1f}M'.format(x*1e-6)
    else:
        s = '${:1.0f}K'.format(x*1e-3)
    return s

formatter = FuncFormatter(currency)

然後可以將此格式化程式應用於繪圖上的標籤。為此將使用軸的xaxis屬性。這使您可以在繪圖上對特定軸執行操作。

fig, ax = plt.subplots(figsize=(6, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(formatter)

繪圖上指定軸

結合多個視覺化

可以在同一軸的axes.Axes範例上繪製多個繪圖元素。要做到這一點,只需要在該軸物件上呼叫另一個繪圖方法。

fig, ax = plt.subplots(figsize=(8, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

# Add a vertical line, here we set the style in the function call
ax.axvline(group_mean, ls='--', color='r')

# Annotate new companies
for group in [3, 5, 8]:
    ax.text(145000, group, "New Company", fontsize=10,
            verticalalignment="center")

# Now we'll move our title up since it's getting a little cramped
ax.title.set(y=1.05)

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(formatter)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)

plt.show()

結合多個可視化

儲存繪圖

如果對繪圖結果感到滿意,並希望將其儲存到磁碟。可以在Matplotlib中儲存許多檔案格式。要檢視可用選項列表,請使用:

print(fig.canvas.get_supported_filetypes())

輸出結果為:

{'ps': 'Postscript', 'eps': 'Encapsulated Postscript', 'pdf': 'Portable Document Format', 'pgf': 'PGF code for LaTeX', 'png': 'Portable Network Graphics', 'raw': 'Raw RGBA bitmap', 'rgba': 'Raw RGBA bitmap', 'svg': 'Scalable Vector Graphics', 'svgz': 'Scalable Vector Graphics', 'jpg': 'Joint Photographic Experts Group', 'jpeg': 'Joint Photographic Experts Group', 'tif': 'Tagged Image File Format', 'tiff': 'Tagged Image File Format'}

然後使用figure.Figure.savefig()來將數位儲存到磁碟。請注意,將在下面顯示幾個有用的標誌:

  • transparent = True如果格式支援,則使儲存的圖形的背景透明。
  • dpi = 80控制輸出的解析度(每平方英寸的點數)。
  • bbox_inches ="tight"符合圖中繪圖的界限。