Seaborn boxplot + stripplot: duplicate legend
You can get what handles/labels should exist in the legend before you actually draw the legend itself. You then draw the legend only with the specific ones you want.
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
tips = sns.load_dataset("tips")
sns.stripplot(x="day", y="total_bill", hue="smoker",
data=tips, jitter=True,
palette="Set2", split=True,linewidth=1,edgecolor='gray')
# Get the ax object to use later.
ax = sns.boxplot(x="day", y="total_bill", hue="smoker",
data=tips,palette="Set2",fliersize=0)
# Get the handles and labels. For this example it'll be 2 tuples
# of length 4 each.
handles, labels = ax.get_legend_handles_labels()
# When creating the legend, only use the first two elements
# to effectively remove the last two.
l = plt.legend(handles[0:2], labels[0:2], bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
I want to add that if you use subplots, the legend handling might be a bit more problematic. The code above, which gives a very nice figure by the way (@Sergey Antopolskiy and @Ffisegydd), will not relocate the legend in a subplot, which keeps appearing very stubbornly. See code above adapted to subplots:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
tips = sns.load_dataset("tips")
fig, axes = sns.plt.subplots(2,2)
sns.stripplot(x="day", y="total_bill", hue="smoker",
data=tips, jitter=True, palette="Set2",
split=True,linewidth=1,edgecolor='gray', ax = axes[0,0])
ax = sns.boxplot(x="day", y="total_bill", hue="smoker",
data=tips,palette="Set2",fliersize=0, ax = axes[0,0])
handles, labels = ax.get_legend_handles_labels()
l = plt.legend(handles[0:2], labels[0:2], bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
The original legend remains. In order to erase it, you can add this line:
axes[0,0].legend(handles[:0], labels[:0])
Edit: in recent versions of seaborn (>0.9.0), this used to leave a small white box in the corner as pointed in the comments. To solve it use the answer in this post:
axes[0,0].get_legend().remove()