目录7

文章Matplotlib第 16 章

多边形填充

Matplotlib · 第 16 / 43 章

fill() —— 多边形填充(任意闭合区域)

fill() 是最底层的一个填充接口:给一串顶点坐标,它连起来并自动闭合。所有“画一个色块”的需求——雷达图底盘、示意图里的区域、流程图色块、自定义图形——最终都可以用它。

Python5 行
Axes.fill(
    *args,           # (x, y) 一组顶点;或 (x1, y1, x2, y2, ...) 多个多边形
    data=None,
    **kwargs         # Patch 属性:facecolor / edgecolor / alpha / hatch / linewidth / zorder
)
调用形式 含义
ax.fill(x, y) 一个多边形,顶点按顺序连,首尾自动闭合
ax.fill(x1, y1, x2, y2) 两个多边形,每两个参数一组
ax.fill("C0", x, y) 带颜色前缀的写法
facecolor / edgecolor 填充色 / 边框色
alpha 透明度;重叠区域深浅叠加
hatch 填充花纹:"/" "\\" "|" "-" "+" "x" "o" "O" "." "*"
linewidth 边框线宽
zorder 图层顺序

最简:一个四边形

Python8 行
import matplotlib.pyplot as plt

x = [0, 1, 1, 0]
y = [0, 0, 1, 1]

fig, ax = plt.subplots()
ax.fill(x, y, color='#4C72B0', alpha=0.5)
plt.show()

多边形填充最小示例

顶点不必首尾重复——fill 会自动闭合。这一点和 Polygon 的构造行为一致,但和 plot 不同(plot 不闭合)。

一次画多个:每两个参数一组

Python1 行
ax.fill(x1, y1, x2, y2)

颜色会按 prop_cycle 自动循环,所以两个多边形自然不同色。不要传 color=[...] 想给每个多边形分别配色:

Python2 行
ax.fill(x1, y1, x2, y2, color=["#4C72B0", "#DD8452"])
# ValueError: RGBA sequence should have length 3 or 4

它把整个列表当成一个 RGBA 序列去解析了。要多色请分两次 fill 调用,或让颜色自动循环。

hatch / edgecolor / facecolor="none"

Python5 行
ax.fill([0, 1, 1, 0], [0, 0, 1, 1], facecolor="#55A868", alpha=0.35,
        edgecolor="#2d6a3f", linewidth=1.5, hatch="//")

ax.fill([1.2, 2.2, 2.2, 1.2], [0, 0, 1, 1], facecolor="none",
        edgecolor="#C44E52", linewidth=1.5, hatch="o")

facecolor="none" + hatch 是「只留纹理、不要底色」的标准写法。注意 hatch 的颜色跟随 edgecolor,改花纹颜色只能改边框色。

花纹密度靠重复字符控制:"//" 比 "/" 密一倍。

任意形状:星形 / 雷达底盘

Python6 行
k = np.arange(10)
r = np.where(k % 2 == 0, 1.0, 0.45)          # 长半径 / 短半径交替
ang = k * np.pi / 5 + np.pi / 2              # 10 个顶点,均分 360°
ax.fill(r * np.cos(ang), r * np.sin(ang), color="#DD8452", alpha=0.55,
        edgecolor="#8c4b1f", linewidth=1.2)
ax.set_aspect("equal")

只要有顶点公式,任何形状都能填。雷达图那种「网格底盘」也是同一个套路:画出 n 边形顶点 → fill(facecolor="none")。

返回对象
Python9 行
polys = ax.fill(x, y)              # list[Polygon]
print(type(polys).__name__, len(polys))
# 输出: list 1

polys[0].set_facecolor("#AEC7E8")
polys[0].set_hatch("//")
polys[0].set_zorder(1)             # 沉到最底层
print(polys[0].get_xy()[:3])       # 顶点坐标 (N+1, 2)
plt.show()

每个多边形一个 Polygon,len(polys) = 多边形个数。get_xy() 返回的顶点比输入多一个——闭合点。

注意事项

  • color=[...] 传列表会报 ValueError: RGBA sequence should have length 3 or 4,多色请分次调用或靠自动循环。
  • 顶点不必首尾重复,fill 自己闭合。
  • hatch 的颜色由 edgecolor 决定,facecolor 管的是底色。
  • 顶点顺序会影响自交多边形(如「8 字形」)的填充结果,按逆时针排最稳。
  • fill 不处理「曲线围成的区域」——两条曲线之间的带请用 fill_between。
  • 填充的默认 zorder 比线低,叠在 plot 下面不用手动设。

综合示例:矩形色块 / 花纹面积 / 星形

Python40 行
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "DejaVu Sans"]
plt.rcParams["axes.unicode_minus"] = False

fig, axes = plt.subplots(1, 3, figsize=(15, 4.4))
t = np.linspace(0, 2 * np.pi, 200)

# ---- (a) 阶段色块:给时间轴分段上底色 ----
axes[0].plot(t, np.sin(t), color="#1f77b4", linewidth=1.6)
axes[0].fill([0, np.pi, np.pi, 0], [-1.1, -1.1, 1.1, 1.1],
             color="#1f77b4", alpha=0.10)
axes[0].fill([np.pi, 2 * np.pi, 2 * np.pi, np.pi], [-1.1, -1.1, 1.1, 1.1],
             color="#DD8452", alpha=0.10)
axes[0].axhline(0, color="gray", linewidth=0.8)
axes[0].set_title("(a) 用 fill 划阶段底色")

# ---- (b) 环形 + 花纹:一个圆减去另一个圆 ----
outer = t
axes[1].fill(np.cos(outer), np.sin(outer), facecolor="#55A868",
             alpha=0.30, edgecolor="#2d6a3f", linewidth=1.2)
axes[1].fill(np.cos(outer) * 0.6, np.sin(outer) * 0.6, facecolor="white",
             edgecolor="#2d6a3f", linewidth=1.2, hatch="..")
axes[1].set_aspect("equal")
axes[1].set_title("(b) 圆 + 白底花纹圆 = 环形")

# ---- (c) 星形色块 ----
k = np.arange(10)
r = np.where(k % 2 == 0, 1.0, 0.45)
ang = k * np.pi / 5 + np.pi / 2
axes[2].fill(r * np.cos(ang), r * np.sin(ang), color="#DD8452",
             alpha=0.55, edgecolor="#8c4b1f", linewidth=1.4)
axes[2].fill(np.cos(t) * 1.15, np.sin(t) * 1.15, facecolor="none",
             edgecolor="gray", linestyle="--", linewidth=1)
axes[2].set_aspect("equal")
axes[2].set_title("(c) 任意闭合形状")

plt.tight_layout()
plt.show()

(b) 那个「内圈盖白底 + 花纹」的做法,是纯 fill 能实现环形的一种土办法——真正的环形还是 pie(wedgeprops=dict(width=...)) 干净。