Skip to content Skip to sidebar Skip to footer

How To Draw Multiple Seaborn `distplot` In A Single Window?

I am trying to draw multiple seaborn distplot in a single window. I know how to generate a density plot for a single list of data, as shown in my code below (make_density function)

Solution 1:

I would use seaborn's FacetGrid class for this.

Simple version:

import seaborn
seaborn.set(style='ticks', context='paper')

axgrid = (
    seaborn.load_dataset('titanic')
        .pipe(seaborn.FacetGrid, hue='deck', col='deck', col_wrap=3, sharey=False)
        .map(seaborn.distplot, 'fare')
)

Or with some modifications to your function:

from matplotlib import pyplot
import seaborn
seaborn.set(style='ticks', context='paper')


# function to plot the histogram for a single list.defmake_density(stat, color=None, x_label=None, y_label=None, ax=None, label=None):
   
    ifnot ax:
        ax = pyplot.gca()
    # Draw the histogram and fit a density plot.
    seaborn.distplot(stat, hist=True, kde=True,
                     kde_kws={'linewidth': 2}, color=color, ax=ax)

    # get the y-coordinates of the points of the density curve.
    dens_list = ax.get_lines()[0].get_data()[1]

    # find the maximum y-coordinates of the density curve.
    max_dens_index = dens_list.argmax()

    # find the mode of the density plot.
    mode_x = ax.get_lines()[0].get_data()[0][max_dens_index]

    # draw a vertical line at the mode of the histogram.
    ax.axvline(mode_x, color=color, linestyle='dashed', linewidth=1.5)
    ymax = ax.get_ylim()[1]
    ax.text(mode_x * 1.1, ymax * 0.16, 'Mode: {:.4f}'.format(mode_x))

    # Plot formatting
    ax.set_xlabel(x_label)
    ax.set_ylabel(y_label)


axgrid = (
    seaborn.load_dataset('titanic')
        .pipe(seaborn.FacetGrid, hue='deck', col='deck', col_wrap=3, sharey=False)
        .map(make_density, 'fare')
)

enter image description here

Solution 2:

You can create a grid of subplots with fig, axes = plt.subplots(...). Then you can provide each 'ax' of the returned 'axes' as the ax= parameter of sns.distplot(). Note that you'll need the same ax to set the labels, plt.xlabel() will only change one of the subplots.

Calling sns.distplot three times is not recommended. sns.distplot will add more and more information to the same ax. Also note that you can use numpy functions such as argmax() to efficiently find the maximum without the need to convert to Python lists (which are quite slow when there is a lot of data).

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# function to plot the histogram for a single list.defmake_density(stat, color, x_label, y_label, ax):
    # Draw the histogram and fit a density plot.
    sns.distplot(stat, hist=True, kde=True,
                 kde_kws={'linewidth': 2}, color=color, ax=ax)

    # get the y-coordinates of the points of the density curve.
    dens_list = ax.get_lines()[0].get_data()[1]

    # find the maximum y-coordinates of the density curve.
    max_dens_index = dens_list.argmax()

    # find the mode of the density plot.
    mode_x = ax.get_lines()[0].get_data()[0][max_dens_index]

    # draw a vertical line at the mode of the histogram.
    ax.axvline(mode_x, color='blue', linestyle='dashed', linewidth=1.5)
    ax.text(mode_x * 1.05, 0.16, 'Mode: {:.4f}'.format(mode_x))

    # Plot formatting
    ax.set_xlabel(x_label)
    ax.set_ylabel(y_label)

stat_list = [[0.3, 0.5, 0.7, 0.3, 0.5], [0.2, 0.1, 0.9, 0.7, 0.4], [0.9, 0.8, 0.7, 0.6, 0.5],
             [0.2, 0.6, 0.75, 0.87, 0.91], [0.2, 0.3, 0.8, 0.9, 0.3], [0.2, 0.3, 0.8, 0.87, 0.92]]
num_subplots = len(stat_list)
ncols = 3
nrows = (num_subplots + ncols - 1) // ncols
fig, axes = plt.subplots(ncols=ncols, nrows=nrows, figsize=(ncols * 6, nrows * 5))
colors = plt.cm.tab10.colors
for ax, stat, color inzip(np.ravel(axes), stat_list, colors):
    make_density(stat, color, 'x_label', 'y_label', ax)
for ax in np.ravel(axes)[num_subplots:]:  # remove possible empty subplots at the end
    ax.remove()
plt.show()

resulting plot

PS: Instead of distplot also histplot (new in Seaborn 0.11) could be used. This should give a nicer plot, especially when the data are few and/or discrete.

sns.histplot(stat, kde=True, line_kws={'linewidth': 2}, color=color, ax=ax)

histplot

Post a Comment for "How To Draw Multiple Seaborn `distplot` In A Single Window?"