{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Animated histogram\n\nUse histogram's `.BarContainer` to draw a bunch of rectangles for an animated\nhistogram.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import functools\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nimport matplotlib.animation as animation\n\n# Setting up a random number generator with a fixed state for reproducibility.\nrng = np.random.default_rng(seed=19680801)\n# Fixing bin edges.\nHIST_BINS = np.linspace(-4, 4, 100)\n\n# Histogram our data with numpy.\ndata = rng.standard_normal(1000)\nn, _ = np.histogram(data, HIST_BINS)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To animate the histogram, we need an ``animate`` function, which generates\na random set of numbers and updates the heights of rectangles. The ``animate``\nfunction updates the `.Rectangle` patches on an instance of `.BarContainer`.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def animate(frame_number, bar_container):\n # Simulate new data coming in.\n data = rng.standard_normal(1000)\n n, _ = np.histogram(data, HIST_BINS)\n for count, rect in zip(n, bar_container.patches):\n rect.set_height(count)\n\n return bar_container.patches" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using :func:`~matplotlib.pyplot.hist` allows us to get an instance of\n`.BarContainer`, which is a collection of `.Rectangle` instances. Since\n`.FuncAnimation` will only pass the frame number parameter to the animation\nfunction, we use `functools.partial` to fix the ``bar_container`` parameter.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Output generated via `matplotlib.animation.Animation.to_jshtml`.\n\nfig, ax = plt.subplots()\n_, _, bar_container = ax.hist(data, HIST_BINS, lw=1,\n ec=\"yellow\", fc=\"green\", alpha=0.5)\nax.set_ylim(top=55) # set safe limit to ensure that all data is visible.\n\nanim = functools.partial(animate, bar_container=bar_container)\nani = animation.FuncAnimation(fig, anim, 50, repeat=False, blit=True)\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. tags:: plot-type: histogram, animation\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 }