Search code examples
pythonseabornaverageswarmplot

Displaying Averages Graphically on Seaborn Swarm Plots


Let's say I have the following seaborn swarmplot:

import seaborn as sns

sns.set_theme(style="whitegrid")
tips = sns.load_dataset("tips")
ax = sns.swarmplot(x="day", y="total_bill", data=tips)

swarmplot

What is a simple way to display the average of each of these swarms on the plots, perhaps with a different symbol, such as an "X"?


Solution

  • You can use pandas' groupby to aggregate the means. And then sns.scatterplot to plot them. For some reason, the scatterplot resets the view limits. You can save xlim and ylim before and reset them afterwards. To have the scatterplot on top of the swarmplot, a zorder can be set (tried with Seaborn 0.11.1):

    import seaborn as sns
    
    sns.set_theme(style="whitegrid")
    tips = sns.load_dataset("tips")
    ax = sns.swarmplot(x="day", y="total_bill", data=tips)
    df_means = tips.groupby("day")["total_bill"].agg("mean").reset_index()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
    sns.scatterplot(x="day", y="total_bill", marker='X', color='black', s=100, zorder=3, ax=ax, legend=False, data=df_means)
    ax.set_xlim(xlim)
    ax.set_ylim(ylim)
    plt.show()
    

    swarmplot with means

    PS: Another workaround to obtain the desired view limits, is first drawing the means (but with zorder at least 4) and afterwards the swarmplot:

    ax = sns.scatterplot(x="day", y="total_bill", marker='X', color='black', s=100, zorder=4, legend=False, data=df_means)
    sns.swarmplot(x="day", y="total_bill", data=tips, ax=ax)
    

    An alternative is to draw the swarmplot on top of a boxplot, as in the last example on the swarmplot's manual page.