{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Building histograms using Rectangles and PolyCollections\n\nUsing a path patch to draw rectangles.\n\nThe technique of using lots of `.Rectangle` instances, or the faster method of\nusing `.PolyCollection`, were implemented before we had proper paths with\nmoveto, lineto, closepoly, etc. in Matplotlib.  Now that we have them, we can\ndraw collections of regularly shaped objects with homogeneous properties more\nefficiently with a PathCollection. This example makes a histogram -- it's more\nwork to set up the vertex arrays at the outset, but it should be much faster\nfor large numbers of objects.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nimport matplotlib.patches as patches\nimport matplotlib.path as path\n\nnp.random.seed(19680801)  # Fixing random state for reproducibility\n\n# histogram our data with numpy\ndata = np.random.randn(1000)\nn, bins = np.histogram(data, 50)\n\n# get the corners of the rectangles for the histogram\nleft = bins[:-1]\nright = bins[1:]\nbottom = np.zeros(len(left))\ntop = bottom + n\n\n# we need a (numrects x numsides x 2) numpy array for the path helper\n# function to build a compound path\nXY = np.array([[left, left, right, right], [bottom, top, top, bottom]]).T\n\n# get the Path object\nbarpath = path.Path.make_compound_path_from_polys(XY)\n\n# make a patch out of it, don't add a margin at y=0\npatch = patches.PathPatch(barpath)\npatch.sticky_edges.y[:] = [0]\n\nfig, ax = plt.subplots()\nax.add_patch(patch)\nax.autoscale_view()\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Instead of creating a three-dimensional array and using\n`~.path.Path.make_compound_path_from_polys`, we could as well create the\ncompound path directly using vertices and codes as shown below\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nrects = len(left)\nnverts = nrects*(1+3+1)\nverts = np.zeros((nverts, 2))\ncodes = np.ones(nverts, int) * path.Path.LINETO\ncodes[0::5] = path.Path.MOVETO\ncodes[4::5] = path.Path.CLOSEPOLY\nverts[0::5, 0] = left\nverts[0::5, 1] = bottom\nverts[1::5, 0] = left\nverts[1::5, 1] = top\nverts[2::5, 0] = right\nverts[2::5, 1] = top\nverts[3::5, 0] = right\nverts[3::5, 1] = bottom\n\nbarpath = path.Path(verts, codes)\n\n# make a patch out of it, don't add a margin at y=0\npatch = patches.PathPatch(barpath)\npatch.sticky_edges.y[:] = [0]\n\nfig, ax = plt.subplots()\nax.add_patch(patch)\nax.autoscale_view()\nplt.show()"
      ]
    },
    {
      "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.patches`\n   - `matplotlib.patches.PathPatch`\n   - `matplotlib.path`\n   - `matplotlib.path.Path`\n   - `matplotlib.path.Path.make_compound_path_from_polys`\n   - `matplotlib.axes.Axes.add_patch`\n   - `matplotlib.collections.PathCollection`\n\n   This example shows an alternative to\n\n   - `matplotlib.collections.PolyCollection`\n   - `matplotlib.axes.Axes.hist`\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
}