I have made a violin plot with swarms like this:
Is it possible to remove just the legend of the swarmplot? It seems the legend has 4 levels, but I just want the first 2 levels.
I tried ax.legend_.remove()
but that remove all the legend.
This is the code I use to make the plot:
import seaborn as sns
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
ax = sns.swarmplot(x="day", y="total_bill", hue = 'smoker', data=tips, color = 'white', dodge=True)
sns.violinplot(x="day", y="total_bill", hue="smoker",data=tips, palette="muted", ax = ax, )
But in the legend, it has four levels, I just hope to remove the legend level for the swarmplot (the black and white dots).
Since I was struggling with the same problem and couldn't find an answer, I decided to provide an answer myself. I am not sure if it's the optimal solution but here we go:
As you already figured out, the legend is stored in ax.legend_
. The legend is simply a matplotlib.legend.Legend
object and you can use its handles (ax.legend_.legendHandles
) and labels (provided in ax.legend_.texts
as a list of matplotlib.text.Text
objects) to update the legend. Calling plt.legend(handles, labels)
with the handles from the violin plot and the corresponding labels recreates the legend without the swarm plot legend entries. (I switched the order of the two plot invocations to make the code simpler.)
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
ax = sns.violinplot(
x="day", y="total_bill", hue="smoker",
data=tips, palette="muted"
)
handles = ax.legend_.legendHandles
labels = [text.get_text() for text in ax.legend_.texts]
sns.swarmplot(
x="day", y="total_bill", hue="smoker",
data=tips, color="white", dodge=True,
ax=ax # you can remove this, it will be plotted on the current axis anyway
)
plt.legend(handles, labels)
plt.show()