{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Apply SVG filter to a line\n\nDemonstrate SVG filtering effects which might be used with Matplotlib.\n\nNote that the filtering effects are only effective if your SVG renderer\nsupport it.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import io\nimport xml.etree.ElementTree as ET\n\nimport matplotlib.pyplot as plt\n\nimport matplotlib.transforms as mtransforms\n\nfig1 = plt.figure()\nax = fig1.add_axes((0.1, 0.1, 0.8, 0.8))\n\n# draw lines\nl1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], \"bo-\",\n              mec=\"b\", lw=5, ms=10, label=\"Line 1\")\nl2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], \"rs-\",\n              mec=\"r\", lw=5, ms=10, label=\"Line 2\")\n\n\nfor l in [l1, l2]:\n\n    # draw shadows with same lines with slight offset and gray colors.\n\n    xx = l.get_xdata()\n    yy = l.get_ydata()\n    shadow, = ax.plot(xx, yy)\n    shadow.update_from(l)\n\n    # adjust color\n    shadow.set_color(\"0.2\")\n    # adjust zorder of the shadow lines so that it is drawn below the\n    # original lines\n    shadow.set_zorder(l.get_zorder() - 0.5)\n\n    # offset transform\n    transform = mtransforms.offset_copy(l.get_transform(), fig1,\n                                        x=4.0, y=-6.0, units='points')\n    shadow.set_transform(transform)\n\n    # set the id for a later use\n    shadow.set_gid(l.get_label() + \"_shadow\")\n\n\nax.set_xlim(0., 1.)\nax.set_ylim(0., 1.)\n\n# save the figure as a bytes string in the svg format.\nf = io.BytesIO()\nplt.savefig(f, format=\"svg\")\n\n\n# filter definition for a gaussian blur\nfilter_def = \"\"\"\n  <defs xmlns='http://www.w3.org/2000/svg'\n        xmlns:xlink='http://www.w3.org/1999/xlink'>\n    <filter id='dropshadow' height='1.2' width='1.2'>\n      <feGaussianBlur result='blur' stdDeviation='3'/>\n    </filter>\n  </defs>\n\"\"\"\n\n\n# read in the saved svg\ntree, xmlid = ET.XMLID(f.getvalue())\n\n# insert the filter definition in the svg dom tree.\ntree.insert(0, ET.XML(filter_def))\n\nfor l in [l1, l2]:\n    # pick up the svg element with given id\n    shadow = xmlid[l.get_label() + \"_shadow\"]\n    # apply shadow filter\n    shadow.set(\"filter\", 'url(#dropshadow)')\n\nfn = \"svg_filter_line.svg\"\nprint(f\"Saving '{fn}'\")\nET.ElementTree(tree).write(fn)"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.14.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}