matplotlib从起点出发(16)_Tutorial_path

0 路径基础初步

本篇我们来学习matplotlib中的path,即“路径”的用法。
path与matplotlib.patches有关。众所周知,patches本义是“补丁”,在绘图中指的是带有边界线的色块面。故而,path指的是这种色块面的边界线。
所有的matplotlib.patches对象的基础对象是Path,它支持一组标准的moveto, lineto, curveto命令,以绘制由线段和样条曲线组成的简单和复合轮廓。Path实例化为 ( N , 2 ) (N, 2) (N,2) ( x , y ) (x, y) (x,y)顶点数组和一个N长度的路径代码数组。例如,要绘制从 ( 0 , 0 ) (0,0) (0,0) ( 1 , 1 ) (1, 1) (1,1)的单位矩形,我们可以使用以下代码:

import numpy as np

import matplotlib.pyplot as plt

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

verts = [
   (0., 0.),  # 左, 下
   (0., 1.),  # 左, 上
   (1., 1.),  # 右, 上
   (1., 0.),  # 右, 下
   (0., 0.),  # 忽略
]

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

path = Path(verts, codes)

fig, ax = plt.subplots()
patch = patches.PathPatch(path, facecolor='orange', lw=2)
ax.add_patch(patch)
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
plt.show()

在这里插入图片描述

路径中常用指令如下:

代码顶点描述
STOP1(忽略)整个路径的最后一个标记点(当前不需要或可忽略)
MOVETO1拾起笔,移动到给定的顶点
LINETO1从当前位置到给定顶点绘制一条线
CURVE32:1个控制点,一个终点绘制一条从当前位置(具有给定控制点)到给定端点的二次贝塞尔曲线
CURVE43:2个控制点,一个终点绘制一条从当前位置(具有给定控制点)到给定端点的三次贝塞尔曲线
CLOSEPOLY1(该点被忽略)绘制一条到当前折线段起点的线段

1 贝塞尔举例

在Matplotlib可视化中定义路径。

某些路径组件需要多个顶点来指定它们:例如,CURVE3 是具有一个控制点和一个端点的贝塞尔曲线,而CURVE4具有两个控制点和端点的三个顶点。下面的示例显示了 CURVE4 贝塞尔 样条曲线 – 贝塞尔 曲线将包含在起点、两个控制点和终点的凸包中:

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, ax = plt.subplots()
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()

在这里插入图片描述

2 复合路径

matplotlib、Rectangle、Circle、Polygon 等中的所有简单Patch都是用简单路径实现的。像 hist()bar() 这样的绘图函数,它们会创建许多基元,例如一堆矩形,通常可以使用复合路径更有效地实现。原因 bar 创建矩形列表而不是复合路径在很大程度上是历史的:路径代码相对较新,并且 bar 早于它。虽然我们现在可以更改它,但它会破坏旧代码,因此在这里我们将介绍如何创建复合路径,替换 bar 中的功能,以防出于效率原因需要在自己的代码中这样做,例如,您正在创建动画条形图。

我们将通过为每个直方图条形创建一系列矩形来制作直方图:矩形宽度是箱的宽度,矩形高度是该箱中的数据点数。首先,我们将创建一些随机的正态分布数据并计算直方图。由于 NumPy 返回 bin 边而不是中心,因此 bins 的长度比以下示例中 n 的长度大 1:

# 使用numpy的数据直方图
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)

现在,我们将提取矩形的角。下面的左边、底部等数组都是 len(n),其中 n 是每个直方图条的计数数组:

# 获取直方图矩形中的角
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n

现在我们必须构造我们的复合路径,它将由每个矩形的一系列 MOVETO、LINETO 和 CLOSEPOLY 组成。对于每个矩形,我们需要五个顶点:一个用于 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)
fig, ax = plt.subplots()
# Fixing random state for reproducibility
np.random.seed(19680801)

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

# 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
nrects = len(left)

nverts = nrects*(1+3+1)
verts = np.zeros((nverts, 2))
codes = np.full(nverts, Path.LINETO, dtype=int)
codes[0::5] = Path.MOVETO
codes[4::5] = 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

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

ax.set_xlim(left[0], right[-1])
ax.set_ylim(bottom.min(), top.max())

plt.show()

在这里插入图片描述

在这里插入图片描述

  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值