Matplotlib——中級

 關於Matplotlib的愚見

初級中,我只是簡單介紹了Matplotlib的使用方法,在中級部分,我係統地說一下我總結的內容。canvas

 

上圖是我畫的關於Matplotlib幾個對象之間的關係圖。它們都來自於一個叫作Artist的基類。咱們知道繪製圖的基礎是Canvas,它是咱們真正進行繪圖的後端。Artist只是在程序邏輯上的繪圖,它必須鏈接後端繪圖程序才能真正在屏幕上繪製出來(或者保存爲文件)。咱們能夠將canvas理解爲繪圖的物理(或者說硬件)實現。對於每一個Artist類的對象,都有findobj()方法,來顯示該對象所包含的全部下層對象。後端

 Artist對象的全部屬性都經過相應的get_*和set_*函數來讀寫。在後面的例子中,不少都不是對fig的操做,而是對ax的操做,這裏要記住這種方法。ide

fig.set_alpha(0.5*fig.get_alpha())

 若是要同時給多個屬性進行設置的話,可使用set函數: 函數

fig.set(alpha = 0.5, zorder=2)

 使用matplotlib.pyplot.getp 函數則能夠方便地輸出Artist對象的全部屬性名和值。字體

plt.getp(fig.patch)

生成多張畫布

好比spa

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 10) print(x) y = x*2+1 z = x**2 plt.figure() plt.plot(x, y) plt.figure() plt.plot(x, z) plt.show()

 運行效果爲:3d

 和   code

若是不寫的話,默認是從1開始算。咱們也能夠在裏面指定參數,用來給這個畫布編號,好比:對象

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 z = x**2 plt.figure() plt.plot(x, y) plt.figure(num=3, figsize=(8, 5)) plt.plot(x, z) plt.show()

 運行效果爲:blog

  和   

座標軸經常使用設置

  • xlim、ylim方法設置座標軸刻度取值範圍
  • xlabel、ylabel方法設置x軸和y軸的標題
  • xticks,yticks方法設置x,y軸的刻度標籤值

例子:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 plt.figure(1) plt.plot(x, y) plt.figure(2) plt.plot(x, y) # 設置座標軸取值範圍
plt.xlim((-2, 2)) plt.ylim((0, 3)) # 設置座標軸標題
plt.xlabel("我是橫座標") plt.ylabel("我是縱座標") # 設置刻度標籤
new_ticks = np.linspace(-1, 4, 6) plt.xticks(new_ticks) # 將原有x軸刻度標註修改,圖也會隨着座標改變而改變。
plt.yticks([1, 2, 3], ["", r"$I\ am\ middle$", ""])     # 用第二個參數的值一一替換第一個參數的值。
 plt.show()

 運行效果爲:

  和   

座標軸邊框設置及位置移動

這裏咱們須要認識的是:gca,它的意思是get current axis(獲取當前軸)。

獲取了當前繪圖區(軸)以後咱們再經過ax.spines對其進行操做,spines是脊柱的意思。

具體的操做以下例:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 plt.figure(1) plt.plot(x, y) plt.figure(2) plt.plot(x, y) # 去掉上和右邊的邊框線
ax = plt.gca()           # 獲取當前繪圖區
ax.spines["right"].set_color("none") ax.spines["top"].set_color("none") # 更改座標軸位置
ax.xaxis.set_ticks_position("bottom")     # 由於繪製的圖形中,上下都算是座標軸,咱們若是要繪製座標系的話須要指定其中一個爲座標軸,這裏咱們是將下座標軸來做爲X軸。
ax.yaxis.set_ticks_position("left")     # 同上,用左軸做爲Y軸。
ax.spines["bottom"].set_position(("data", 0))  # data表示用值來選擇,這個句話的意思就是用X座標軸上值爲0的點做爲座標系原點。"data"只是一個參數,還有outward,axes等參數,它們都有不一樣的意義。
ax.spines["left"].set_position(("data", 0))   # 同上
 plt.show()

  運行結果爲:

  和     

圖例的設置

在初級,咱們說過簡單的設置圖例,這裏咱們在進行一些拓展的說明。

例子:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 z = x**2 plt.figure(1) L1, = plt.plot(x, y, label="$x*2+1$")  # L1後面的逗號是matplotlib特殊的寫法
L2, = plt.plot(x, z, label="$x^2$") plt.legend(handles=[L1], labels=["a", "b"], loc="best") # handles是用來控制放入圖例的內容。labels是用來給handles對應的圖修改圖例名。
 plt.show()

 運行結果爲:

在圖片中添加註解

在講解給圖片添加註解以前呢,咱們須要認識一下scattter函數,咱們在繪製圖像的時候使用的是plot,它是線的形式,若是咱們使用scatter的話,它就會用點的形式來繪製。 

 下面是示例代碼:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = x*2+1 plt.figure(1) plt.plot(x, y) plt.figure(2) plt.plot(x, y) # 去掉上和右邊的邊框線
ax = plt.gca()           # 獲取當前繪圖區
ax.spines["right"].set_color("none") ax.spines["top"].set_color("none") # 更改座標軸位置
ax.xaxis.set_ticks_position("bottom")     # 由於繪製的圖形中,上下都算是座標軸,咱們若是要繪製座標系的話須要指定其中一個爲座標軸,這裏咱們是將下座標軸來做爲X軸。
ax.yaxis.set_ticks_position("left")     # 同上,用左軸做爲Y軸。
ax.spines["bottom"].set_position(("data", 0))  # data表示用值來選擇,這個句話的意思就是用X座標軸上值爲0的點做爲座標系原點。"data"只是一個參數,還有outward,axes等參數,它們都有不一樣的意義。
ax.spines["left"].set_position(("data", 0))   # 同上

# 設置標註
x0 = 1 y0 = 2*x0 + 1 plt.scatter(x0, y0, s=50, color="b")      # 設置要標註的點,scatter和plot函數同樣能夠繪製圖形,不過它是用點構成的圖形。其中s是控制大小,color是控制顏色。
plt.plot([x0, x0], [y0, 0], "k--", lw=1)    # 設置一個黑色的虛線。
 plt.annotate(r'$2x+1=%s$' % y0, xy=(x0, y0), xycoords='data', xytext=(+30, -30), textcoords='offset points', fontsize=16, arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=.2")) """ 下面是annotate中每一個參數設置的意思: plt.annotate(r"$2x+1\ =\ %s$" % y0, # 標註的文字描述 xy=(x0, y0), # xy是設置要標註的點。 xycoords="data", # xycoords表示前面xy設置的內容以"data"的值爲基準。 xytext=(+30, -30), # 標註信息在要標註的點的橫座標加30,縱座標減30的位置顯示。 textcoords="offset point", # xtext設置的內容以"offset point",也就是偏移量爲基準。 fontsize=16, # 設置字體的大小 arrowprops=dict(arrowstyle="->", connectionstyle="arc3, rad=.2") # 設置箭頭。arrowstyle的設置表示使用箭頭,connectionstyle是用來設置弧度的。 ) """ plt.text(-3.7, 3, r'$This\ is\ the\ some\ text. \mu\ \sigma_i\ \alpha_t$', fontdict={'size': 16, 'color': 'r'}) """ 下面是text中每一個參數設置的意思: plt.text(-3.7, 3, # 文字顯示的位置 r'$This\ is\ the\ some\ text. \mu\ \sigma_i\ \alpha_t$', # 顯示的文字 fontdict={'size': 16, 'color': 'r'}) # 文字的格式 """ plt.show()

 運行結果以下:

  和   

當線遮擋刻度標註解決辦法

示例代碼:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 50) y = 0.1*x plt.figure() # 在 plt 2.0.2 或更高的版本中, 設置 zorder 給 plot 在 z 軸方向排序
plt.plot(x, y, linewidth=10, zorder=1) plt.ylim(-2, 2) ax = plt.gca() ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.spines['bottom'].set_position(('data', 0)) ax.yaxis.set_ticks_position('left') ax.spines['left'].set_position(('data', 0)) for label in ax.get_xticklabels() + ax.get_yticklabels(): label.set_fontsize(12)    # 設置字體大小
 label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.7, zorder=2)) """ set_bbox的參數說明: label.set_bbox(dict(facecolor='white', # 背景顏色 edgecolor='None', # 邊框 alpha=0.7, # 背景透明度 zorder=2)) # 在 plt 2.0.2 或更高的版本中, 設置 zorder 給 plot 在 z 軸方向排序 """ plt.show()

 運行結果:

 同畫布繪製多圖

方式1:使用subplot來繪製

在初級中,咱們說過咱們畫一個圖是要在一個畫布上,咱們畫的圖在Matplotlib中被稱爲軸或者繪圖區,一個畫布中能夠包含多個繪圖區,每一個繪圖區都擁有本身座標系統的繪圖區域。咱們能夠經過subplot()函數來快速繪製有多個繪圖區的畫布。

它的格式爲:

plt.subplot(numRows, numCols, plotNum)

 subplot將整個繪圖區域劃分爲numRows行和numCols列個區域,而後按照從左到右,從上到下的順序對每一個子區域進行編號,以下圖所示。

在使用的時候,有的人可能會看到subplot(324)這樣的設置,這樣也是正確的寫法,它等效於subplot(3, 2, 3)。若是numRows、numCols、plotNum這三個數都小於10的話,能夠把它們縮寫爲一個整數。

若是新建的軸和以前的軸位置重疊的話,原來的軸會被覆蓋。

使用例子以下:

import matplotlib.pyplot as plt plt.figure() plt.subplot(2, 2, 1) plt.plot([0, 1], [0, 1]) plt.subplot(2, 2, 2) plt.plot([0, 1], [0, 2]) plt.subplot(223) plt.plot([0, 1], [0, 3]) plt.subplot(224) plt.plot([0, 1], [0, 4]) plt.show()

 運行效果爲:

咱們還能夠自定義它們的跨列顯示

import matplotlib.pyplot as plt plt.figure() plt.subplot(2, 1, 1) plt.plot([0, 1], [0, 1]) plt.subplot(2, 3, 4) plt.plot([0, 1], [0, 2]) plt.subplot(235) plt.plot([0, 1], [0, 3]) plt.subplot(236) plt.plot([0, 1], [0, 4]) plt.show()

 運行代碼以下:

 

說明:

使用subplot是比較彆扭的,要大概瞭解它的繪製順序。在上面例子中,

(2, 1, 1),第一個參數表示figure分爲兩行,第二個參數表示分爲一列,第三個表示它使用第一個圖繪製。

(2, 3, 4),第一個參數表示figure分爲兩行,第二個參數表示分爲三列,第三個表示它使用第四個圖繪製(由於第一行是跨3列,因此這個是從第四個開始計算)。(2, 3, 5)和(2, 3, 6)同理。

 不一樣figure切換加figure切分的例子:

import numpy as np
import matplotlib.pyplot as plt 

plt.figure(1)
plt.figure(2)
ax1= plt.subplot(221)
ax2 = plt.subplot(222)
ax3 = plt.subplot(212)
x = np.linspace(0, 3, 100)
for i in range(5):
    plt.figure(1)
    plt.plot(x, np.exp(i*x/3))
    plt.sca(ax1)
    plt.plot(x, np.sin(i*x))
    plt.sca(ax2)
    plt.plot(x, np.cos(i*x))
    plt.sca(ax3)
    plt.plot(x, np.exp(i*x/3))
plt.show()

 它的效果如圖:

 從上面的例子中咱們能夠看出:使用subplot()會返回它所建立的繪圖區,經過變量保存後,咱們可使用sca()函數交替讓它們成爲當前繪圖區,而後調用plot()函數在這個繪圖區裏面繪製圖形。若是有多個畫布,咱們能夠用figure()函數來指定一個畫布。若是這個畫布存在則將該畫布變爲當前畫布,若是不存在則建立一個對應的畫布。

方式2:使用subplot2grid來繪製

subplot2grid使用起來要比第一種subplot的方式要更直觀和清晰些。咱們來看看例子:

import matplotlib.pyplot as plt plt.figure() ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3, rowspan=1)   # 第一個參數是整個figure分爲幾個塊,第一個爲行,第二個爲列;第二個參數爲這個圖形的起始位置,位置是從0開始計算的;第三個和第四個分別設置這個圖形佔據幾列和幾行。 ax1.plot([1, 2], [2, 2]) ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2) ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2) ax4 = plt.subplot2grid((3, 3), (2, 0)) ax5 = plt.subplot2grid((3, 3), (2, 1))

 運行結果:

方式3:使用gridspec來繪製

使用它以前咱們要先導入:

import matplotlib.gridspec as gridspec

 讓咱們再看看實際的使用:

import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec plt.figure() gs = gridspec.GridSpec(3, 3) # 將一個figure分紅3*3的格子。
 ax1= plt.subplot(gs[0, :])     # 佔第0行和全部列
ax2 = plt.subplot(gs[1, :2])    # 佔第1行和第2列前的全部列
ax3 = plt.subplot(gs[1:, 2])   # 佔第1行後的全部行和第2列
ax4 = plt.subplot(gs[-1, 0])    # 佔倒數第1行和第0列
ax5 = plt.subplot(gs[-1, -2])  # 佔倒數第1行和倒數第2列.

 運行結果:

方式4:使用subplots來繪製

注意,這個和第一種方法不一樣,第一種建立方式咱們使用的是subplot,這裏咱們使用的是subplots。

 使用例子:

import matplotlib.pyplot as plt f,((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex=True, sharey=False) plt.tight_layout() # 不加會緊湊顯示
ax1.plot([1, 2], [2, 2])   # ax1中繪製圖像。
plt.show() """ 說明: 使用plt.subplots創建一個2行2列的圖像窗口, sharex=True表示共享x軸座標, sharey=True表示共享y軸座標。 ((ax11, ax12), (ax13, ax14))表示第1行從左至右依次放ax1和ax2, 第2行從左至右依次放ax3和ax4. """

 運行效果:

 繪製圖內圖

代碼:

# 導入pyplot模塊
import matplotlib.pyplot as plt # 初始化figure
fig = plt.figure() # 建立數據
x = [1, 2, 3, 4, 5, 6, 7] y = [1, 3, 4, 2, 5, 8, 6] left, bottom, width, height = 0.1, 0.1, 0.8, 0.8    # 4個值都是佔整個figure座標系的百分比。在這裏,假設figure的大小是10x10,那麼大圖左邊距爲1,底邊距爲1,寬8,高8的座標系內。

# 繪製外圍圖
ax1 = fig.add_axes([left, bottom, width, height]) ax1.plot(x, y, 'r') ax1.set_xlabel('x') ax1.set_ylabel('y') ax1.set_title('title') # 繪製內圖
left, bottom, width, height = 0.2, 0.5, 0.3, 0.3 ax2 = fig.add_axes([left, bottom, width, height])   # 假設figure的大小是10x10,那麼大圖左邊距爲2,底邊距爲5,寬3,高3的座標系內。
ax2.plot(y, x, 'b') ax2.set_xlabel('x') ax2.set_ylabel('y') ax2.set_title('title inside 1')

 運行結果爲:

相關文章
相關標籤/搜索