路徑教程
原文: 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()

下面的路徑代碼會被接受:
代碼 | 頂點 | 描述 |
---|---|---|
| 1 (被忽略) | 标志整個路徑終點的标記(目前不需要或已忽略) |
| 1 | 提起筆并移動到指定頂點 |
| 從目前位置向指定頂點畫線 | |
| 2 (一個控制點,一個終點) | 從目前位置,以給定控制點向給定端點畫貝塞爾曲線 |
| 3 (兩個控制點,一個終點) | 從目前位置,以給定控制點向給定端點畫三次貝塞爾曲線 |
| 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,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)
結果為: