How To Draw Multiple Seaborn `distplot` In A Single Window?
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')
)
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()
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)
Post a Comment for "How To Draw Multiple Seaborn `distplot` In A Single Window?"