Search code examples
pythonseaborn

Frequency in seaborn histograms


I have a dataset of used cars. I have made a histogram plot for the count of cars by their age (in months).

sns.distplot(df['Age'],kde=False,bins=6)

And the plot looks something like this:

enter image description here

Is there any way I can depict the frequency values of each bin in the plot itself

PS: I know I can fetch the values using the numpy histogram function which is

np.histogram(df['Age'],bins=6)

Basically I want the plot to look somewhat like this I guess so:

enter image description here


Solution

  • Since this question was first answered, sns.distplot has been replaced by sns.histplot (and sns.kdeplot). Also, matplotlib now has a function to label bars.

    New answer: with sns.histplot() and ax.bar_label

    import matplotlib.pyplot as plt
    import numpy as np
    import seaborn as sns
    import pandas as pd
    
    sns.set_style('darkgrid')
    df = pd.DataFrame({'Age': np.random.triangular(1, 80, 80, 1000).astype(int)})
    ax = sns.histplot(df['Age'], kde=False, bins=6)
    
    ax.bar_label(ax.containers[0], color='crims
    
    on')
    plt.show()
    

    sns.histplot with labeled frequencies

    Old answer: with sns.distplot() and manual annotations

    You can iterate over the patches belonging to the ax, get their position and height, and use these to create annotations.

    import matplotlib.pyplot as plt
    import numpy as np
    import seaborn as sns
    import pandas as pd
    
    sns.set_style()
    df = pd.DataFrame({'Age': np.random.triangular(1, 80, 80, 1000).astype(np.int)})
    ax = sns.distplot(df['Age'], kde=False, bins=6)
    
    for p in ax.patches:
        ax.annotate(f'{p.get_height():.0f}\n',
                    (p.get_x() + p.get_width() / 2, p.get_height()), ha='center', va='center', color='crimson')
    plt.show()
    

    example plot