{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# SVG filter pie\n\nDemonstrate SVG filtering effects which might be used with Matplotlib.\nThe pie chart drawing code is borrowed from pie_demo.py\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\nfrom matplotlib.patches import Shadow\n\n# make a square figure and Axes\nfig = plt.figure(figsize=(6, 6))\nax = fig.add_axes((0.1, 0.1, 0.8, 0.8))\n\nlabels = 'Frogs', 'Hogs', 'Dogs', 'Logs'\nfracs = [15, 30, 45, 10]\n\nexplode = (0, 0.05, 0, 0)\n\n# We want to draw the shadow for each pie, but we will not use \"shadow\"\n# option as it doesn't save the references to the shadow patches.\npie = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%')\n\nfor w in pie.wedges:\n    # set the id with the label.\n    w.set_gid(w.get_label())\n\n    # we don't want to draw the edge of the pie\n    w.set_edgecolor(\"none\")\n\nfor w in pie.wedges:\n    # create shadow patch\n    s = Shadow(w, -0.01, -0.01)\n    s.set_gid(w.get_gid() + \"_shadow\")\n    s.set_zorder(w.get_zorder() - 0.1)\n    ax.add_patch(s)\n\n\n# save\nf = io.BytesIO()\nplt.savefig(f, format=\"svg\")\n\n\n# Filter definition for shadow using a gaussian blur and lighting effect.\n# The lighting filter is copied from http://www.w3.org/TR/SVG/filters.html\n\n# I tested it with Inkscape and Firefox3. \"Gaussian blur\" is supported\n# in both, but the lighting effect only in Inkscape. Also note\n# that, Inkscape's exporting also may not support it.\n\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='2'/>\n    </filter>\n\n    <filter id='MyFilter' filterUnits='objectBoundingBox'\n            x='0' y='0' width='1' height='1'>\n      <feGaussianBlur in='SourceAlpha' stdDeviation='4%' result='blur'/>\n      <feOffset in='blur' dx='4%' dy='4%' result='offsetBlur'/>\n      <feSpecularLighting in='blur' surfaceScale='5' specularConstant='.75'\n           specularExponent='20' lighting-color='#bbbbbb' result='specOut'>\n        <fePointLight x='-5000%' y='-10000%' z='20000%'/>\n      </feSpecularLighting>\n      <feComposite in='specOut' in2='SourceAlpha'\n                   operator='in' result='specOut'/>\n      <feComposite in='SourceGraphic' in2='specOut' operator='arithmetic'\n    k1='0' k2='1' k3='1' k4='0'/>\n    </filter>\n  </defs>\n\"\"\"\n\n\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 i, pie_name in enumerate(labels):\n    pie = xmlid[pie_name]\n    pie.set(\"filter\", 'url(#MyFilter)')\n\n    shadow = xmlid[pie_name + \"_shadow\"]\n    shadow.set(\"filter\", 'url(#dropshadow)')\n\nfn = \"svg_filter_pie.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
}