pythonseabornviolin-plotpointplot

Problem with order of elements when combining violin and point plot in seaborn


I am trying to make a combined plot using seaborn - violin plot with sticks inside and the mean+std pointplot on top of it. I have three categories that I want to use for hue. Somehow, the leftmost pointplot is hidden behind the inner part of violinplot (sticks, or whatever I put in there) - the rest is fine. Like this:

import seaborn as sns
import matplotlib.pyplot as plt

data =  sns.load_dataset('titanic')

fig, ax1 = plt.subplots(1, 1)

sns.violinplot(data=data, x='alive', y='age', hue='class', palette='muted', size=2, inner='stick', ax=ax1)
ax1.legend_.remove()
fig.legend(loc='upper center', ncol=3, title='Class')

sns.pointplot(data=data, x='alive', y='age', hue='class', dodge=.54, join=False, errorbar='sd', capsize=0.05, palette='dark', ax=ax1,)
ax1.legend_.remove()

fig.tight_layout()
fig.subplots_adjust(top=0.85)

plot

I want all pointplots to be above all of the violinplots. I tried using zorder, but it doesn't work with seaborn. Is there a way to set it up, or some other function/library that I can use to achieve it?


Solution

  • You can actually use zorder not directly in seaborn but inside plt.setp() to change the property of an Artist. Here is an example code snippet:

    import seaborn as sns
    import matplotlib.pyplot as plt
    
    data =  sns.load_dataset('titanic')
    fig, ax1 = plt.subplots(1, 1)
    sns.pointplot(data=data, x='alive', y='age', hue='class', dodge=.54, join=False, errorbar='sd', capsize=0.05, palette='dark', ax=ax1)
    ax1.legend_.remove()
    plt.setp(ax1.lines, zorder=100)
    plt.setp(ax1.collections, zorder=100, label="")
    sns.violinplot(data=data, x='alive', y='age', hue='class', palette='muted', size=2, inner='stick', ax=ax1)
    ax1.legend_.remove()
    fig.legend(loc='upper center', ncol=3, title='Class')
    fig.tight_layout()
    fig.subplots_adjust(top=0.85)
    

    which produces the following output: enter image description here