{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# A pie and a donut with labels\n\nWelcome to the Matplotlib bakery. We will create a pie and a donut\nchart through the `pie method <matplotlib.axes.Axes.pie>` and\nshow how to label them with a `legend <matplotlib.axes.Axes.legend>`\nas well as with the `pie_label method <matplotlib.axes.Axes.pie>` and\n`annotations <matplotlib.axes.Axes.annotate>`.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "As usual we would start by defining the imports and create a figure with\nsubplots.\nNow it's time for the pie. Starting with a pie recipe, we create the data\nand a list of labels from it.\n\nWe then create the pie and store the returned `~matplotlib.container.PieContainer`\nobject for later.\n\nWe can provide the `~matplotlib.container.PieContainer` and a format string to\nthe `~matplotlib.axes.Axes.pie_label` method to automatically label each\ningredient's wedge with its weight in grams and percentages.\n\nThe `~.PieContainer` has a list of patches as one of its attributes.  Those are\n`matplotlib.patches.Wedge` patches, which can directly be used as the handles\nfor a legend. We can use the legend's ``bbox_to_anchor`` argument to position\nthe legend outside of the pie. Here we use the axes coordinates ``(1, 0, 0.5,\n1)`` together with the location ``\"center left\"``; i.e. the left central\npoint of the legend will be at the left central point of the bounding box,\nspanning from ``(1, 0)`` to ``(1.5, 1)`` in axes coordinates.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nfig, ax = plt.subplots(figsize=(6, 3))\n\nrecipe = [\"375 g flour\",\n          \"75 g sugar\",\n          \"250 g butter\",\n          \"300 g berries\"]\n\ndata = [int(x.split()[0]) for x in recipe]\ningredients = [x.split()[-1] for x in recipe]\n\npie = ax.pie(data)\n\nax.pie_label(pie, '{frac:.1%}\\n({absval:d}g)',\n             textprops=dict(color=\"w\", size=8, weight=\"bold\"))\n\nax.legend(pie.wedges, ingredients,\n          title=\"Ingredients\",\n          loc=\"center left\",\n          bbox_to_anchor=(1, 0, 0.5, 1))\n\nax.set_title(\"Matplotlib bakery: A pie\")\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now it's time for the donut. Starting with a donut recipe, we transcribe\nthe data to numbers (converting 1 egg to 50 g), and directly plot the pie.\nThe pie? Wait... it's going to be donut, is it not?\nWell, as we see here, the donut is a pie, having a certain ``width`` set to\nthe wedges, which is different from its radius. It's as easy as it gets.\nThis is done via the ``wedgeprops`` argument.\n\nWe then want to label the wedges via\n`annotations <matplotlib.axes.Axes.annotate>`. We first create some\ndictionaries of common properties, which we can later pass as keyword\nargument. We then iterate over all wedges and for each\n\n* calculate the angle of the wedge's center,\n* from that obtain the coordinates of the point at that angle on the\n  circumference,\n* determine the horizontal alignment of the text, depending on which side\n  of the circle the point lies,\n* update the connection style with the obtained angle to have the annotation\n  arrow point outwards from the donut,\n* finally, create the annotation with all the previously\n  determined parameters.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect=\"equal\"))\n\nrecipe = [\"225 g flour\",\n          \"90 g sugar\",\n          \"1 egg\",\n          \"60 g butter\",\n          \"100 ml milk\",\n          \"1/2 package of yeast\"]\n\ndata = [225, 90, 50, 60, 100, 5]\n\npie = ax.pie(data, wedgeprops=dict(width=0.5), startangle=-40)\n\nbbox_props = dict(boxstyle=\"square,pad=0.3\", fc=\"w\", ec=\"k\", lw=0.72)\nkw = dict(arrowprops=dict(arrowstyle=\"-\"),\n          bbox=bbox_props, zorder=0, va=\"center\")\n\nfor i, p in enumerate(pie.wedges):\n    ang = (p.theta2 - p.theta1)/2. + p.theta1\n    y = np.sin(np.deg2rad(ang))\n    x = np.cos(np.deg2rad(ang))\n    horizontalalignment = {-1: \"right\", 1: \"left\"}[int(np.sign(x))]\n    connectionstyle = f\"angle,angleA=0,angleB={ang}\"\n    kw[\"arrowprops\"].update({\"connectionstyle\": connectionstyle})\n    ax.annotate(recipe[i], xy=(x, y), xytext=(1.35*np.sign(x), 1.4*y),\n                horizontalalignment=horizontalalignment, **kw)\n\nax.set_title(\"Matplotlib bakery: A donut\")\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "And here it is, the donut. Note however, that if we were to use this recipe,\nthe ingredients would suffice for around 6 donuts - producing one huge\ndonut is untested and might result in kitchen errors.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. admonition:: References\n\n   The use of the following functions, methods, classes and modules is shown\n   in this example:\n\n   - `matplotlib.axes.Axes.pie` / `matplotlib.pyplot.pie`\n   - `matplotlib.axes.Axes.pie_label` / `matplotlib.pyplot.pie_label`\n   - `matplotlib.axes.Axes.legend` / `matplotlib.pyplot.legend`\n\n.. tags::\n\n   component: label\n   component: annotation\n   plot-type: pie\n   level: beginner\n\n"
      ]
    }
  ],
  "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
}