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()

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.