MWE
from matplotlib import pyplot as plt
import seaborn as sb
df = sb.load_dataset("titanic")
g = sb.catplot(
data=df, x="who", y="survived", hue="class",
kind="bar"
)
plt.tight_layout()
plt.savefig('bah.png')
Figure looks bad because the legend is transparent. How do I change its opacity and how can I add a black border around the legend?
For figure-level plots such as sns.catplot()
, which create a grid with one or more subplots, seaborn creates a figure legend. For figure-level plots with only one subplot, you can use the axes-level equivalent, which here would be sns.barplot()
. These have more standard legend, by default, inside the subplot.
To change the properties of a seaborn legend, it is recommended to use sns.move_legend()
. A minor inconvenience is that move_legend()
needs you to explicitly set a position. To get a border, frameon=True
and edgecolor=...
is needed.
Unfortunately, plt.tight_layout()
doesn't take the figure legend into account. You can call plt.subplots_adjust(right=...)
to again create space such that the legend doesn't overlap with the rightmost subplot.
Here is some example code:
from matplotlib import pyplot as plt
import seaborn as sns
df = sns.load_dataset("titanic")
g = sns.catplot(
data=df, x="who", y="survived", hue="class",
kind="bar"
)
sns.move_legend(g, frameon=True, facecolor='lightgrey', edgecolor='black',
loc='center right', bbox_to_anchor=(1, 0.5))
plt.tight_layout()
plt.subplots_adjust(right=0.8) # mitigate overlapping legend due to tight_layout
plt.show()
PS: Using the standard shortening for seaborn helps to match your code with the documentation and makes it easier to find similar examples on sites such as StackOverflow.