Catplot¶
https://seaborn.pydata.org/generated/seaborn.catplot.html
order,hue_order: lists of strings, optional\ Order to plot the categorical levels in; otherwise the levels are inferred from the data objects.row_order,col_order: lists of strings, optional\ Order to organize the rows and/or columns of the grid in, otherwise the orders are inferred from the data objects.
catplot with bar type¶
Use catplot() to combine a barplot() and a FacetGrid - data should not be in index:
smoker = list(data['smoker'].unique())
time = list(data['time'].unique())
g = sns.catplot(
kind='bar',
data=tips,
x='sex',
order=['male', 'dfemale'], #order for the x value
y='total_bill',
row='smoker',
row_order=smoker,
col='time',
col_order=time,
sharey=False,
ci=None, #remove error bars
height=4,
aspect=0.7,
)
#ylim, gridline, annotation
# get the (min, max) of the val column for each group (smoker, time)
ylims = (
d.groupby(['smoker','time'])
.agg(vmin=('val', 'min'), vmax=('val', 'max'))
.assign(
tmin=lambda x: x[['vmin']].groupby(['smoker']).transform('min'),
tmax=lambda x: x[['vmax']].groupby(['smiker']).transform('max'),
)
.drop(columns=['vmin','vmax'])
.assign(tmin=lambda x: x.tmin * 0.99)
.reindex(pd.MultiIndex.from_product([smoker, time])) #keep row/col order
.to_records(index=False)
)
for i, ax in enumerate(g.axes.ravel()):
ax.set_ylim(ylims[i])
ax.grid(visible=True, which='major', color='black', linewidth=0.075)
for c in ax.containers:
labels = [f'{v.get_height():.3f}' for v in c]
ax.bar_label(c, labels=labels, label_type='edge', rotation=90, fontsize=8)