Matplotlib SVG Filter Line

PythonPythonBeginner

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

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии показано, как использовать SVG-фильтры с Matplotlib. Фильтры действуют только в том случае, если SVG-рендерer поддерживает их.

Советы по работе с ВМ

После запуска виртуальной машины кликните в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

Иногда может потребоваться подождать несколько секунд, пока Jupyter Notebook не загрузится полностью. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.

Если вы сталкиваетесь с проблемами при обучении, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.

Импортируем необходимые библиотеки

Сначала нам нужно импортировать необходимые библиотеки: matplotlib.pyplot, io и xml.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 и сохраняем фигуру в виде строки байтов в формате SVG с использованием io.BytesIO() и plt.savefig().

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

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

Определяем фильтр

Мы определяем фильтр для гауссовского размытия с использованием тегов <defs> и <filter> с атрибутом stdDeviation.

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

Мы читаем сохраненный SVG с использованием ET.XMLID() и вставляем определение фильтра в дерево DOM SVG с использованием tree.insert(). Затем мы выбираем элемент SVG с заданным ID и применяем фильтр тени с использованием 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)

Резюме

В этом практическом занятии показано, как использовать эффекты фильтрации SVG с Matplotlib. Мы узнали, как создавать фигуру и оси, рисовать линии и тени, задавать пределы осей и определять и применять фильтры к SVG.