{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Histograms\n\nHow to plot histograms with Matplotlib.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\nimport numpy as np\n\nfrom matplotlib import colors\nfrom matplotlib.ticker import PercentFormatter\n\n# Create a random number generator with a fixed seed for reproducibility\nrng = np.random.default_rng(19680801)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generate data and plot a simple histogram\n\nTo generate a 1D histogram we only need a single vector of numbers. For a 2D\nhistogram we'll need a second vector. We'll generate both below, and show\nthe histogram for each vector.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "N_points = 100000\nn_bins = 20\n\n# Generate two normal distributions\ndist1 = rng.standard_normal(N_points)\ndist2 = 0.4 * rng.standard_normal(N_points) + 5\n\nfig, axs = plt.subplots(1, 2, sharey=True, tight_layout=True)\n\n# We can set the number of bins with the *bins* keyword argument.\naxs[0].hist(dist1, bins=n_bins)\naxs[1].hist(dist2, bins=n_bins)\n\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Updating histogram colors\n\nThe histogram method returns (among other things) a ``patches`` object. This\ngives us access to the properties of the objects drawn. Using this, we can\nedit the histogram to our liking. Let's change the color of each bar\nbased on its y value.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(1, 2, tight_layout=True)\n\n# N is the count in each bin, bins is the lower-limit of the bin\nN, bins, patches = axs[0].hist(dist1, bins=n_bins)\n\n# We'll color code by height, but you could use any scalar\nfracs = N / N.max()\n\n# we need to normalize the data to 0..1 for the full range of the colormap\nnorm = colors.Normalize(fracs.min(), fracs.max())\n\n# Now, we'll loop through our objects and set the color of each accordingly\nfor thisfrac, thispatch in zip(fracs, patches):\n color = plt.cm.viridis(norm(thisfrac))\n thispatch.set_facecolor(color)\n\n# We can also normalize our inputs by the total number of counts\naxs[1].hist(dist1, bins=n_bins, density=True)\n\n# Now we format the y-axis to display percentage\naxs[1].yaxis.set_major_formatter(PercentFormatter(xmax=1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot a 2D histogram\n\nTo plot a 2D histogram, one only needs two vectors of the same length,\ncorresponding to each axis of the histogram.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, ax = plt.subplots(tight_layout=True)\nhist = ax.hist2d(dist1, dist2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Customizing your histogram\n\nCustomizing a 2D histogram is similar to the 1D case, you can control\nvisual components such as the bin size or color normalization.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(3, 1, figsize=(5, 15), sharex=True, sharey=True,\n tight_layout=True)\n\n# We can increase the number of bins on each axis\naxs[0].hist2d(dist1, dist2, bins=40)\n\n# As well as define normalization of the colors\naxs[1].hist2d(dist1, dist2, bins=40, norm=colors.LogNorm())\n\n# We can also define custom numbers of bins for each axis\naxs[2].hist2d(dist1, dist2, bins=(80, 10), norm=colors.LogNorm())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. tags::\n\n plot-type: histogram,\n plot-type: histogram2d\n domain: statistics\n styling: color,\n component: normalization\n component: patch\n\n.. 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.hist` / `matplotlib.pyplot.hist`\n - `matplotlib.pyplot.hist2d`\n - `matplotlib.ticker.PercentFormatter`\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.13.2" } }, "nbformat": 4, "nbformat_minor": 0 }