Reputation: 1496
I'm using seaborn.displot to display a distribution of scores for a group of participants.
Is it possible to have the y axis show an actual percentage (example below)?
This is required by the audience for the data. Currently it is done in excel but It would be more useful in python.
import seaborn as sns
data = sns.load_dataset('titanic')
p = sns.displot(data=data, x='age', hue='sex', height=4, kind='kde')
Upvotes: 1
Views: 9603
Reputation: 62383
seaborn.displot
is a figure-level plot providing access to several approaches for visualizing the univariate or bivariate distribution of data (histplot, kdeplot, ecdfplot)common_bins
and common_norm
.python 3.8.12
, pandas 1.3.4
, matplotlib 3.4.3
, seaborn 0.11.2
data
is a pandas dataframe, and seaborn
is an API for matplotlib
.kind='hist'
: seaborn.histplot
stat='percent'
→ available from seaborn 0.11.2
import seaborn as sns
from matplotlib.ticker import PercentFormatter
data = sns.load_dataset('titanic')
p = sns.displot(data=data, x='age', stat='percent', hue='sex', height=4, kde=True, kind='hist')
kind='kde'
: seaborn.kdeplot
seaborn
: you can wrap a percent formatter around a density value (as shown in the following code), but it's incorrect because the density is not a proportion (you may end up with values > 100%).matplotlib.ticker.PercentFormatter
to convert the axis values.import seaborn as sns
from matplotlib.ticker import PercentFormatter
data = sns.load_dataset('titanic')
p = sns.displot(data=data, x='age', hue='sex', height=3, kind='kde')
p.axes.flat[0].yaxis.set_major_formatter(PercentFormatter(1))
Upvotes: 4
Reputation: 48992
As mentioned by @JohanC, the y axis for a KDE is a density, not a proportion, so it does not make sense to convert it to a percentage.
You'd have two options. One would be to plot a KDE curve over a histogram with histogram counts expressed as percentages:
sns.displot(
data=tips, x="total_bill", hue="sex",
kind="hist", stat="percent", kde=True,
)
But your "desired plot" actually doesn't look like a density at all, it looks like a histogram plotted with a line instead of bars. You can get that with element="poly"
:
sns.displot(
data=tips, x="total_bill", hue="sex",
kind="hist", stat="percent", element="poly", fill=False,
)
Upvotes: 2