天天看點

Matplotlib 中文使用者指南 3.8 路徑教程路徑教程

路徑教程

原文: Path Tutorial 譯者: 飛龍 協定: CC BY-NC-SA 4.0

位于所有

matplotlib.patch

對象底層的對象是

Path

,它支援

moveto

lineto

curveto

指令的标準幾個,來繪制由線段和樣條組成的簡單和複合輪廓。 路徑由

(x,y)

頂點的

(N,2)

數組,以及路徑代碼的長度為 N 的數組執行個體化。 例如,為了繪制

(0,0)

(1,1)

的機關矩形,我們可以使用這個代碼:

import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches

verts = [
    (0., 0.), # left, bottom
    (0., 1.), # left, top
    (1., 1.), # right, top
    (1., 0.), # right, bottom
    (0., 0.), # ignored
    ]

codes = [Path.MOVETO,
         Path.LINETO,
         Path.LINETO,
         Path.LINETO,
         Path.CLOSEPOLY,
         ]

path = Path(verts, codes)

fig = plt.figure()
ax = fig.add_subplot(111)
patch = patches.PathPatch(path, facecolor='orange', lw=2)
ax.add_patch(patch)
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
plt.show()           
Matplotlib 中文使用者指南 3.8 路徑教程路徑教程

下面的路徑代碼會被接受:

代碼 頂點 描述

STOP

1 (被忽略) 标志整個路徑終點的标記(目前不需要或已忽略)

MOVETO

1 提起筆并移動到指定頂點

LINETO

從目前位置向指定頂點畫線

CURVE3

2 (一個控制點,一個終點) 從目前位置,以給定控制點向給定端點畫貝塞爾曲線

CURVE4

3 (兩個控制點,一個終點) 從目前位置,以給定控制點向給定端點畫三次貝塞爾曲線

CLOSEPOLY

1 (點自身被忽略) 向目前折線的起點畫線

貝塞爾示例

一些路徑元件需要以多個頂點來指定:例如

CURVE3

是具有一個控制點和一個端點的貝塞爾曲線,

CURVE4

具有用做兩個控制點和端點的三個頂點。 下面的示例顯示了

CURVE4

貝塞爾曲線 - 貝塞爾曲線将包含在起始點,兩個控制點和終點的凸包中:

import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches

verts = [
    (0., 0.),  # P0
    (0.2, 1.), # P1
    (1., 0.8), # P2
    (0.8, 0.), # P3
    ]

codes = [Path.MOVETO,
         Path.CURVE4,
         Path.CURVE4,
         Path.CURVE4,
         ]

path = Path(verts, codes)

fig = plt.figure()
ax = fig.add_subplot(111)
patch = patches.PathPatch(path, facecolor='none', lw=2)
ax.add_patch(patch)

xs, ys = zip(*verts)
ax.plot(xs, ys, 'x--', lw=2, color='black', ms=10)

ax.text(-0.05, -0.05, 'P0')
ax.text(0.15, 1.05, 'P1')
ax.text(1.05, 0.85, 'P2')
ax.text(0.85, -0.05, 'P3')

ax.set_xlim(-0.1, 1.1)
ax.set_ylim(-0.1, 1.1)
plt.show()           
Matplotlib 中文使用者指南 3.8 路徑教程路徑教程

複合路徑

所有在 matplotlib,Rectangle,Circle,Polygon 等中的簡單更新檔原語都是用簡單的路徑實作的。通過使用複合路徑,通常可以更有效地實作繪制函數,如

hist()

bar()

,它們建立了許多原語,例如一堆

Rectangle

,通常可使用複合路徑來實作。

bar

建立一個矩形清單,而不是一個複合路徑,很大程度上出于曆史原因:路徑代碼是比較新的,

bar

在它之前就存在。雖然我們現在可以改變它,但它會破壞舊的代碼,是以如果你需要為了效率,在你自己的代碼中這樣做,例如,建立動畫條形圖,在這裡我們将介紹如何建立複合路徑,替換

bar

中的功能。

我們将通過為每個直方圖的條形建立一系列矩形,來建立直方圖圖表:矩形寬度是條形的寬度,矩形高度是該條形中的資料點數量。首先,我們将建立一些随機的正态分布資料并計算直方圖。因為 numpy 傳回條形邊緣而不是中心,是以下面的示例中

bins

的長度比

n

的長度大 1:

# histogram our data with numpy
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)           

我們現在将提取矩形的角。 下面的每個

left

bottom

等數組長度為

len(n)

,其中

n

是每個直方圖條形的計數數組:

# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n           

現在我們必須構造複合路徑,它由每個矩形的一系列

MOVETO

LINETO

CLOSEPOLY

組成。 對于每個矩形,我們需要 5 個頂點:一個代表

MOVETO

,三個代表

LINETO

,一個代表

CLOSEPOLY

。 如上表所示,

closepoly

的頂點被忽略,但我們仍然需要它來保持代碼與頂點對齊:

nverts = nrects*(1+3+1)
verts = np.zeros((nverts, 2))
codes = np.ones(nverts, int) * path.Path.LINETO
codes[0::5] = path.Path.MOVETO
codes[4::5] = path.Path.CLOSEPOLY
verts[0::5,0] = left
verts[0::5,1] = bottom
verts[1::5,0] = left
verts[1::5,1] = top
verts[2::5,0] = right
verts[2::5,1] = top
verts[3::5,0] = right
verts[3::5,1] = bottom           

剩下的就是建立路徑了,将其添加到

PathPatch

,将其添加到我們的軸域:

barpath = path.Path(verts, codes)
patch = patches.PathPatch(barpath, facecolor='green',
  edgecolor='yellow', alpha=0.5)
ax.add_patch(patch)           

結果為:

Matplotlib 中文使用者指南 3.8 路徑教程路徑教程