'Sort seaborn catplot by value counts within each facet

I am close but not quite there. I am trying to sort an sns.catplot by value counts within each grouping.

Code and Output:

fig = plt.subplots(dpi=300)
plt.figure(figsize=(10, 10))

grid = sns.catplot(data=df, kind='count', y='violation_raw', row='stop_duration', height=4, aspect=3,
                   sharey=False, palette="dark:salmon_r",
                   order=df['violation_raw'].value_counts(ascending=False).index)

ax = grid.axes[0, 0]
ax.bar_label(ax.containers[0])
ax = grid.axes[1, 0]
ax.bar_label(ax.containers[0])
ax = grid.axes[2, 0]
ax.bar_label(ax.containers[0])

plt.xlabel("Count", labelpad=12)

plt.margins(x=0.2)
plt.tight_layout()
plt.show()

enter image description here

It is listing the rows in the exact same order per grouping, but they are not sorted by value counts within each grouping.

I want to sort, by value_counts() the rows in each respective grouping.



Solution 1:[1]

It is listing the rows in the exact same order per grouping, but they are not sorted by value counts within each grouping.

This is because order is currently set to the global value counts. I'm not sure it's possible to set a different order per facet.

One option is to pass the groupby.value_counts() directly as the data and plot the grouped counts with kind='bar':

grid = sns.catplot(
    data=df.groupby('stop_duration')['violation_raw'].value_counts().reset_index(name='violation_count'),
    kind='bar', x='violation_count', y='violation_raw', row='stop_duration',
    height=4, aspect=3, sharey=False, palette='dark:salmon_r')

for ax in grid.axes.flat:
    ax.bar_label(ax.containers[0])

counts sorted within groups

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tdy