Search code examples
pythonmatplotlibseabornboxplotswarmplot

How to add a mean line to a seaborn stripplot or swarmplot


I have a rather simple strip plot with vertical data.

planets = sns.load_dataset("planets")
sns.stripplot(x="method", y="distance", data=planets, size=4, color=".7")
plt.xticks(rotation=45, ha="right")
plt.show()

I want to plot the mean of each x-element (method) as a small horizontal bar similar to what you get with:

sns.boxplot(
    x="method",
    y="distance",
    data=planets,
    whis=[50, 50],
    showfliers=False,
    showbox=False,
    showcaps=False
)

But without the vertical lines (with whis=[50,50] just spots) for the first / third quartile and showing mean instead of median. Maybe there is a more elegant solution not involving a Boxplot.


Solution

    • Boxplot objects are defined in matplotlib.pyplot.boxplot
      • showmeans=True
      • meanline=True makes a line instead of a marker
      • meanprops={'color': 'k', 'ls': '-', 'lw': 2} sets the color, style and width of the line.
      • medianprops={'visible': False} makes the median line not visible
      • whiskerprops={'visible': False} makes the whisker line not visible
      • zorder=10 places the line on the top layer
    • Tested in matplotlib v3.4.2 and seaborn v0.11.1
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    # load the dataset
    planets = sns.load_dataset("planets")
    
    p = sns.stripplot(x="method", y="distance", data=planets, size=4, color=".7")
    plt.xticks(rotation=45, ha="right")
    p.set(yscale='log')
    
    # plot the mean line
    sns.boxplot(showmeans=True,
                meanline=True,
                meanprops={'color': 'k', 'ls': '-', 'lw': 2},
                medianprops={'visible': False},
                whiskerprops={'visible': False},
                zorder=10,
                x="method",
                y="distance",
                data=planets,
                showfliers=False,
                showbox=False,
                showcaps=False,
                ax=p)
    plt.show()
    

    enter image description here

    • Works similarly with a seaborn.swarmplot

    enter image description here