Saturday, February 2, 2013

#matplotlib: Comparative histogram recipe

When comparing the distributions of two related data sets, it often makes sense to present the data on a comparative histogram, i.e. two histograms, one for each data set, contrasted against each other. 

Comparative histograms could be used to demonstrate a change in performance when many enough samples are available (e.g. latency of calls to a server), or compare two statistical populations, e.g. age pyramid. 
Here is the code:
"""comphist.py"""

import numpy as np
import matplotlib.pyplot as plt

def comphist(x1, x2, orientation='vertical', **kwargs):
    """Draw a comparative histogram."""
    # Split keyword args:
    kwargs1 = {}
    kwargs2 = {}
    kwcommon = {}
    for arg in kwargs:
        tgt_arg = arg[:-1]
        if arg.endswith('1'):
            arg_dict = kwargs1
        elif arg.endswith('2'):
            arg_dict = kwargs2
        else:
            arg_dict = kwcommon
            tgt_arg = arg
        arg_dict[tgt_arg] = kwargs[arg]
    kwargs1.update(kwcommon)
    kwargs2.update(kwcommon)

    fig = plt.figure()

    # Have both histograms share one axis.
    if orientation == 'vertical':
        ax1 = plt.subplot(211)
        ax2 = plt.subplot(212, sharex=ax1)
        # Flip the ax2 histogarm horizontally.
        ax2.set_ylim(ax2.get_ylim()[::-1])
        plt.setp(ax1.get_xticklabels(), visible=False)
        legend_loc = (1, 4)
    else:
        ax1 = plt.subplot(122)
        ax2 = plt.subplot(121, sharey=ax1)
        # Flip the ax2 histogarm vertically.
        ax2.set_xlim(ax2.get_xlim()[::-1])
        plt.setp(ax1.get_yticklabels(), visible=False)
        legend_loc = (1, 2)

    ax1.hist(x1, orientation=orientation, **kwargs1)
    ax2.hist(x2, orientation=orientation, **kwargs2)
    ax1.legend(loc=legend_loc[0])
    ax2.legend(loc=legend_loc[1])
    # Tighten up the layout.    
    plt.subplots_adjust(wspace=0.0, hspace=0.0)
    return fig

if __name__ == "__main__":
    comphist(np.random.randn(1000), np.random.randn(1000), 
             label1='before', label2='after', color2='green', bins=30, rwidth=1)
    plt.show()

1 comment:

  1. It's been barely a few months since the release of Fifa 17 game, and work has already started for the release of the next version of the FIFA

    series, the Fifa 18. It will obviously have some more added features and a few updates as well. You can check out the rumors about the new specs

    from my site here if you want Fifa 18 release date

    ReplyDelete