matplotlib入門之Pyplot

lilongsy發表於2017-06-07

Pyplot教程

matplotlib.pyplot是一些命令樣式函式,像MATLAB一樣。每一個pyplot函式都會改變圖形,例如建立圖形、在圖行裡建立繪圖區、在繪圖區畫線、用標籤裝飾圖形等。在pyplot的函式呼叫中,隱藏了各種狀態,這就意味著要始終跟蹤到當前的圖形和繪圖區域,並且繪圖函式要指向當前的座標軸(注意這裡的座標軸是數字座標軸,而不是嚴格意義的數學術語)。

import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()

pyplot_simple

你可能會疑惑為什麼x軸範圍從0-3,而y軸從1-4。如果只給plot()提供了一個單獨的列表或陣列,那麼matplotlib就假設這些是y軸上的數值序列,然後自動為你生成x軸的數值。python的取值範圍預設從0開始,預設x向量長度和y軸一樣,但是是從0開始的。因此x的數值列表就是[0,1,2,3]。

plot()是一個通用的命令,可以接收任意數量的引數。例如,想同時繪製x和y軸,你可以發出一下命令:

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

對於每對x,y引數,還有一個可選的第三個引數,它是用來表示線條顏色和型別的格式串。這個格式串的字母和標記來自於MATLAB,你可以把顏色字串和線條樣式字串連結起來。預設的格式字串是’b-‘,表示綠色實線。例如,為了把上圖用紅圈繪製,可以執行一下命令:

import matplotlib.pyplot as plt
plt.plot([1,2,3,4], [1,4,9,16], 'ro')
plt.axis([0, 6, 0, 20])
plt.show()

pyplot_formatstr

plot()文件裡可以看到完整的線樣式和格式串。
axis()命令在上面例子中收到一串引數[xmin, xmax, ymin, ymax],用來指定座標軸的視窗。

如果matplotlib僅限於處理一維列表,那麼對於數字處理來說將是相當受限的。通常使用numpy陣列。實際上所有的序列都內部轉換成了numpy陣列。下面的示例演示了用不同的陣列樣式繪畫幾條線。

import numpy as np
import matplotlib.pyplot as plt

# evenly sampled time at 200ms intervals
t = np.arange(0., 5., 0.2)

# red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()

pyplot_three

控制線條屬性

線條有很多屬性,你可以設定:線寬、破折樣式等。詳情見文件。有很多種方法設定線條屬性:

  • 使用關鍵詞引數。
plt.plot(x, y, linewidth=2.0)
  • 使用Line2D物件的setter方法。plot函式返回Line2D物件列表,例如line1, line2 = plot(x1, y1, x2, y2)。在下面的程式碼中,我們假設只有一行,因此返回的列表長度為1。我們使用元組來拆開line,並獲取到列表的第一個元素。
line, = plt.plot(x, y, '-')
line.set_antialiased(False) # turn off antialising
  • 使用setp()命令。下面的示例使用MATLAB樣式的命令在一行上設定多個屬性。setp透明的使用一組或一個物件。你既可以使用關鍵詞引數,也可以使用MATLAB形式的鍵值對。
lines = plt.plot(x1, y1, x2, y2)
# use keyword args
plt.setp(lines, color='r', linewidth=2.0)
# or MATLAB style string value pairs
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)

Line2D屬性見文件

獲取可設定的Line屬性,可以呼叫setp()函式,並且引數是line或lines。

In [69]: lines = plt.plot([1, 2, 3])

In [70]: plt.setp(lines)
  alpha: float
  animated: [True | False]
  antialiased or aa: [True | False]
  ...snip

多圖和多座標軸

MATLAB、pyplot都有當前圖和當前座標軸的概念。所有的會話命令都應用與當前座標軸。gca()返回當前的座標軸(matplotlib.axes.Axes例項),gcf()返回當前圖(matplotlib.figure.Figure例項)。一般,你不必關係這些,因為這些都在幕後執行。下面程式碼建立兩個子圖。

import numpy as np
import matplotlib.pyplot as plt

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

pyplot_two_subplots

這兒的figure()命令是可選的,因為figure(1)會被預設執行,就像subplot(111)也會被預設執行,只要你不手動定義任何的座標軸。subplot()命令指定行數(numrows)、列數(numcols)、圖形號(fignum),圖形號的範圍是從1到numrows*numcols。如果numrows*numcols<10,subplot()引數裡的逗號是可選的。所以subplot(211)等同於subplot(2, 1, 1)。你可以建立任意數量的子圖和座標軸。如果你想手動放置座標軸,例如不在一個直角網格里,可以使用axes()命令,axes可以讓你給座標軸定義位置,像axes([left, bottom, width, height]),引數都是小數(0-1)座標。兩個例子:

你通過呼叫多次引數遞增的figure()來建立多個圖形。當然,每個圖形可以包含儘可能多的座標軸和子圖。

import matplotlib.pyplot as plt
plt.figure(1)                # the first figure
plt.subplot(211)             # the first subplot in the first figure
plt.plot([1, 2, 3])
plt.subplot(212)             # the second subplot in the first figure
plt.plot([4, 5, 6])


plt.figure(2)                # a second figure
plt.plot([4, 5, 6])          # creates a subplot(111) by default

plt.figure(1)                # figure 1 current; subplot(212) still current
plt.subplot(211)             # make subplot(211) in figure1 current
plt.title('Easy as 1, 2, 3') # subplot 211 title

你可以使用clf()清除當前圖形,使用cla()清除當前座標軸。如果你對這些幕後維護的狀態(指定當前的圖片、圖形和座標軸)感覺彆扭,不要灰心:這只是一個物件導向API的少部分狀態包裝器,你可以使用替代方案,詳見Artist tutorial

如果你要建立多個圖形,你需要知道一件事:為一個圖形分配的內容沒有完全釋放,直到圖形明確的呼叫了close()。刪除所有圖形引用,或者關閉螢幕上的視窗管理器,也不能完全釋放記憶體,因為pyplot在維護內部的引用,只有呼叫close()才可以。

文字處理

text()命令可以在任意位置新增文字。xlabel()ylabel()title()也可以新增文字到指定的地方。詳見Text介紹

import numpy as np
import matplotlib.pyplot as plt

# Fixing random state for reproducibility
np.random.seed(19680801)

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

# the histogram of the data
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)


plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()

pyplot_text

所有的text()命令返回一個matplotlib.text.Text物件。就像上面提到的lines,你可以通過關鍵詞引數或setp()自定義屬性。

t = plt.xlabel('my data', fontsize=14, color='red')

詳情見文件

在text裡使用數學表示式

matplotlib可以在任何文字表示式中接收TeX方程表示式。例如你可以用美元符包住一個Tex表示式。

plt.title(r'$\sigma_i=15$')

標題字元前的r很重要,他標識字串是原生字串,不需要python轉義加反斜線。matplotli有一個內建的表示式解析器和結構引擎,提供自己的數學字型,詳情見文件。因此你可以跨平臺使用數學文字,而不必安裝Tex。對於那些已經安裝了LaTex和dvipng的人,您還可以使用LaTex來格式化文字,並將輸出直接合併到顯示數字或儲存的postscript中。詳情見文件

文字註釋

使用基本的text()命令可以把文字放到任意位置。文字註釋圖形的特徵,通常annotate()提供幫助功能,可以讓註釋容易。在一個註釋方法裡,這裡有兩點要注意:要註釋的位置xy,文字說明的位置xytext。這些引數都是(x,y)元組。

import numpy as np
import matplotlib.pyplot as plt

ax = plt.subplot(111)

t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)

plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
            arrowprops=dict(facecolor='black', shrink=0.05),
            )

plt.ylim(-2,2)
plt.show()

pyplot_annotate

在這個基本例子中,xy(箭頭提示)和xytext(文字位置)都在資料座標裡。還有很多可選的其他座標系統。詳見基本註釋高階註釋。更多例子見demo

對數和其他非線性座標軸

matplotlib.pyplot不僅支援線性軸刻度,還支援對數和對數刻度。如果資料跨越多個數量級,這通常會被使用。改變軸的尺度很簡單:

plt.xscale(‘log’)

下面顯示了一個包含相同資料和y軸不同刻度的四個圖。

import numpy as np
import matplotlib.pyplot as plt

from matplotlib.ticker import NullFormatter  # useful for `logit` scale

# Fixing random state for reproducibility
np.random.seed(19680801)

# make up some data in the interval ]0, 1[
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))

# plot with various axes scales
plt.figure(1)

# linear
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)


# log
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)


# symmetric log
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthreshy=0.01)
plt.title('symlog')
plt.grid(True)

# logit
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
# Format the minor tick labels of the y-axis into empty strings with
# `NullFormatter`, to avoid cumbering the axis with too many labels.
plt.gca().yaxis.set_minor_formatter(NullFormatter())
# Adjust the subplot layout, because the logit one may take more space
# than usual, due to y-tick labels like "1 - 10^{-3}"
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
                    wspace=0.35)

plt.show()

pyplot_scales

你也可以增加自己的刻度,詳見開發者指南

翻譯來自:http://matplotlib.org/users/pyplot_tutorial.html

相關文章