Fast histogram (code snippet)

This is a 24x faster version of the histogram plot. It is not intended for inclusion into the Matplotlib code-base (unless you want to). It is just a small code-snippet in case someone else needs a much faster version of the histogram plot.

When len(x) is 500k and bins=100 then Matplotlib’s original ax.hist function takes around 360 milli-sec for me, while this version only takes around 15 milli-sec, thus giving a 24x speedup. It also saves a significant amount of time when saving the plot, around 150 milli-sec for me. That’s a total saving of around 0.5 second.

This is of course not necessary for most use-cases, but it is useful to people who are doing real-time / low-latency plotting. I saved enough runtime that it was worth it to me.

import numpy as np

def hist_fast(ax, x, bins, density=False, **kwargs):
    """Fast histogram plotting. More than 20x faster than `ax.hist`
    
    :param ax: Matplotlib Axes object.
    :param x: Array with data.
    :param density: See np.histogram.
    :param kwargs: Extra keyword-args passed to `ax.fill_between`
    """
    # Calculate histogram bins and edges.
    hist, bin_edges = np.histogram(x, bins=bins, density=density)

    # Repeat histogram bins and edges to create steps.
    hist_steps = np.repeat(hist, 2)
    bin_edges_steps = np.repeat(bin_edges, 2)[1:-1]

    # Plot solid color as histogram.
    ax.fill_between(bin_edges_steps, 0.0, hist_steps, **kwargs)
    
    # Adjust y-axis limits.
    _, y_max = ax.get_ylim()
    ax.set_ylim(0.0, y_max)

I think this may be doing what passing the histtype='stepfilled' argument does?

Thanks, it looks like you’re right!

Note to self: Must read a function’s doc-string before making a new version of the function :slight_smile:

It takes around 40 milli-sec with ax.hist(histtype='stepfilled', ...) which would have been fine for me. For those who need it even faster, they can still use the above.