Matplotlib SVG 滤镜线条

PythonPythonBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

本实验演示如何在Matplotlib中使用SVG过滤效果。只有当你的SVG渲染器支持时,过滤效果才会有效。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问Jupyter Notebook进行练习。

有时,你可能需要等待几秒钟让Jupyter Notebook完成加载。由于Jupyter Notebook的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向Labby提问。课程结束后提供反馈,我们会及时为你解决问题。

导入所需库

首先,我们需要导入所需的库:matplotlib.pyplotioxml.etree.ElementTree

import io
import xml.etree.ElementTree as ET
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms

创建图形和坐标轴

我们使用 plt.figure() 创建一个图形对象,并使用 fig1.add_axes() 添加一个坐标轴对象。我们还使用 [0.1, 0.1, 0.8, 0.8] 设置坐标轴的大小和位置。

fig1 = plt.figure()
ax = fig1.add_axes([0.1, 0.1, 0.8, 0.8])

绘制线条

我们使用 ax.plot() 绘制两条线。我们还使用不同的颜色、标记和标签对线条进行定制。

l1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-", mec="b", lw=5, ms=10, label="Line 1")
l2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], "rs-", mec="r", lw=5, ms=10, label="Line 2")

绘制阴影

我们通过使用与原线条稍有偏移且为灰色的相同线条来为线条绘制阴影。我们调整阴影线条的颜色和z轴顺序,使其绘制在原始线条下方。我们还使用 offset_copy() 方法为阴影线条创建一个偏移变换。

for l in [l1, l2]:
    xx = l.get_xdata()
    yy = l.get_ydata()
    shadow, = ax.plot(xx, yy)
    shadow.update_from(l)

    shadow.set_color("0.2")
    shadow.set_zorder(l.get_zorder() - 0.5)

    transform = mtransforms.offset_copy(l.get_transform(), fig1, x=4.0, y=-6.0, units='points')
    shadow.set_transform(transform)

    shadow.set_gid(l.get_label() + "_shadow")

设置坐标轴范围并保存图形

我们设置坐标轴的x和y范围,并使用 io.BytesIO()plt.savefig() 将图形保存为SVG格式的字节字符串。

ax.set_xlim(0., 1.)
ax.set_ylim(0., 1.)

f = io.BytesIO()
plt.savefig(f, format="svg")

定义滤镜

我们使用带有 stdDeviation 属性的 <defs><filter> 标签来定义高斯模糊滤镜。

filter_def = """
  <defs xmlns='http://www.w3.org/2000/svg'
        xmlns:xlink='http://www.w3.org/1999/xlink'>
    <filter id='dropshadow' height='1.2' width='1.2'>
      <feGaussianBlur result='blur' stdDeviation='3'/>
    </filter>
  </defs>
"""

读取并修改SVG

我们使用 ET.XMLID() 读取保存的SVG,并使用 tree.insert() 将滤镜定义插入到SVG DOM树中。然后,我们通过给定的ID获取SVG元素,并使用 shadow.set() 应用阴影滤镜。

tree, xmlid = ET.XMLID(f.getvalue())

tree.insert(0, ET.XML(filter_def))

for l in [l1, l2]:
    shadow = xmlid[l.get_label() + "_shadow"]
    shadow.set("filter", 'url(#dropshadow)')

fn = "svg_filter_line.svg"
print(f"Saving '{fn}'")
ET.ElementTree(tree).write(fn)

总结

本实验展示了如何在Matplotlib中使用SVG过滤效果。我们学习了如何创建图形和坐标轴、绘制线条和阴影、设置坐标轴范围,以及定义并将滤镜应用于SVG。