mwaskom / seaborn

Statistical data visualization in Python
https://seaborn.pydata.org
BSD 3-Clause "New" or "Revised" License
12.18k stars 1.89k forks source link

Split violin plots not working #3697

Closed mlldantas closed 1 month ago

mlldantas commented 1 month ago

Hi,

I am trying to re-run a previous code that worked very well to create grouped asymmetrical violin plots. I am getting several errors that were not happening (maybe 6 months ago) and now am I trying to constrain the errors. I think one of the issues is that I am not providing an x= value (because when I run Seaborn's example, it works, albeit the deprecation warnings).

The code is rather complicated because it's two violin plots with another tiny one zoomed into a range I want to show. The error is happening very early, when I try to run the sns.violinplot. This is the full code:

# Applying the custom configurations
plt.rcParams.update(plotpars_1x2)

# Create a figure with two subplots
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# First violin plot for age_median_gyr
sns.violinplot(ax=axes[0], y='age_median_gyr', hue='Type', data=catplot_bpsm_01, 
               split=True,  
               inner="quart", 
               palette={"Observed": palette[1], "Sim01": palette[-1]}, 
               bw_method=.3, cut=1, linewidth=1., alpha=alpha, saturation=saturation)
axes[0].set_ylabel(r"$\langle t_{\star} \rangle$ (Gyr)")
axes[0].set_title(r"Before PSM - $\langle t_{\star} \rangle$ (Gyr)")
axes[0].get_legend().remove()
axes[0].set_xticks([])

# Customize the legend for the first plot
leg = axes[0].legend(title=r"Dataset", loc="lower left")
new_labels = [r"Gaia-ESO", 'Simulation 01']
for t, l in zip(leg.get_texts(), new_labels): 
    t.set_text(l)

# Second violin plot for FEH
sns.violinplot(ax=axes[1], y='FEH', hue='Type', data=catplot_bpsm_01, 
               split=True, 
               inner="quart", 
               palette={"Observed": palette[1], "Sim01": palette[-1]}, 
               bw_method=.3, cut=1, linewidth=1., alpha=alpha, saturation=saturation)
axes[1].set_ylabel(r"[Fe/H]")
axes[1].set_title(r"Before PSM - [Fe/H]")
axes[1].get_legend().remove()
axes[1].set_xticks([])

axins = inset_axes(axes[1], width="35%", height="35%", loc=4)

sns.violinplot(y='FEH', hue='Type', data=catplot_bpsm_01, 
               split=True, 
               inner="quart", 
               palette={"Observed": palette[1], "Sim01": palette[-1]}, 
               bw_method=.3, cut=1, linewidth=1., alpha=alpha, saturation=saturation)

axins.set_ylim([-1.1, 0.7])
# axins.set_ylabel(r"[Fe/H]")
axins.set_ylabel("")
axins.get_legend().remove()
axins.set_yticks([0.5, 0., -0.5, -1])
axins.set_yticklabels(axins.get_yticks(), fontsize=14)
axins.tick_params(axis='y', which='major', labelsize=14)

plt.tight_layout(w_pad=2.)

plt.show()

The error is happening here already:


# First violin plot for age_median_gyr
sns.violinplot(ax=axes[0], y='age_median_gyr', hue='Type', data=catplot_bpsm_01, 
               split=True,  
               inner="quart", 
               palette={"Observed": palette[1], "Sim01": palette[-1]}, 
               bw_method=.3, cut=1, linewidth=1., alpha=alpha, saturation=saturation)

When I simplify this with:

sns.violinplot(data=catplot_bpsm_01, y="age_median_gyr", hue="Type", inner="quart", split=True)

I am not getting a split violin, I am getting a regular violin. It is completely ignoring the split part. When I add the palette part, palette={"Observed": palette[1], "Sim01": palette[-1]}, it gives me this message:


TypeError Traceback (most recent call last) Cell In[110], line 2 1 plt.rcParams.update(plotpars_1x1) ----> 2 sns.violinplot(data=catplot_bpsm_01, y="age_median_gyr", hue="Type", inner="quart", split=True, palette={"Observed": palette[1], "Sim01": palette[-1]}) 3 plt.show()

TypeError: 'NoneType' object is not subscriptable

I have no idea why this is happening. This is the image I was previously generating with the original code above:

Screenshot from 2024-05-25 16-07-56

Also, this is the shape of the data I am using:

Screenshot from 2024-05-25 16-10-47

Current Seaborn version: 0.12.2

mwaskom commented 1 month ago

Hi, please reduce this to a minimal, self-contained example. It's not really possible for me to help based on the information here.

jhncls commented 1 month ago

Testing something similar with seaborn 0.12.2 indeed gives a non-split violin:

tips = sns.load_dataset('tips')
sns.violinplot(data=tips, y='tip', hue='time', inner='quart', split=True)

image

Luckily, that problem doesn't exist anymore in the latest seaborn 0.13.2

image

Upgrading seaborn would be the way forward.

About the other problem: if sns.violinplot(data=catplot_bpsm_01, y="age_median_gyr", hue="Type", inner="quart", split=True, palette={"Observed": palette[1], "Sim01": palette[-1]}) only gives TypeError: 'NoneType' object is not subscriptable, without further error trace, the most probable cause would be that you have a variable palette which is None. You could try print("palette:", palette) to find out what's inside.

mwaskom commented 1 month ago

Thanks @jhncls

mlldantas commented 1 month ago

Hi, thanks @jhncls for checking it. I had tried to show in my request where the problem was, which could be reproduced using Seaborn's embedded examples.

I understand you already closed the issue, but when I opened it I had updated my Seaborn package. It seems that version 0.12.2 is the latest one available for conda updates. Therefore, my problem persists.

Screenshot from 2024-05-29 17-44-31

mwaskom commented 1 month ago

Seaborn v0.13.0 was released on PyPI in September 2023 (and there have been a couple additional releases since).

The main anaconda channel is very slow to update packages so if you want to use the conda tool to manage your packages it is strongly recommended to use the conda-forge channel, which typically updates quickly after a PyPI release. I do not have any ability to influence the anaconda update cadence.

mlldantas commented 1 month ago

Cool, thanks for explaining that. I just updated it using pip and github actually. I will test if everything runs smoothly.

mlldantas commented 1 month ago

FYI, everything worked smoothly with version 0.13.2, including the palette. Thank you for your help!