I'm plotting a scatterplot with matplotlib and seaborn. Hhere is my output.

As you can see at the right on the legend there are many labels with the same color, I'm trying to erase all the grays but one. Here is my code:
background = '#eeeeee'
high_c = '#5a83aa'
low_c = '#e09a67'
neutral_c = '#fff8c2'
palette = {'Western Europe':high_c,
'North America and ANZ':'#cccccc',
'Middle East and North Africa':'#cccccc',
'Latin America and Caribbean':'#cccccc',
'Central and Eastern Europe':'#cccccc',
'East Asia':'#cccccc',
'Southeast Asia':'#cccccc',
'Commonwealth of Independent States':'#cccccc',
'Sub-Saharan Africa':low_c,
'South Asia':'#cccccc'
}
fig, ax = plt.subplots(1,1, figsize=(10, 5),dpi=120)
fig.patch.set_facecolor(background) # figure background color
ax.set_facecolor(background)
# plots
sns.scatterplot(data=df21, x='Healthy life expectancy', y='Ladder score',
hue=df21['Regional indicator'],
palette=palette, alpha=0.95,ec='black',
size=df21["Logged GDP per capita"]*1000, legend=True, sizes=(5, 500))
# Axes
ax.set_xlabel("Healthy Life Expectancy",fontfamily='sans serif',loc='left',color='gray')
ax.set_ylabel("Happiness Index Score",fontfamily='sans serif',loc='top',color='gray')
ax.tick_params(axis = 'both', which = 'major', labelsize = 10)
for s in ["top","right","left"]:
ax.spines[s].set_visible(False)
# Annotations
ax.text(45,9.2,'Happiness Score, Life Expectancy, and GDP per Capita',
fontfamily='sans serif',fontweight='normal',fontsize=17,weight='bold',color='#323232')
# Legend
L = ax.legend(frameon=False,loc="upper center", bbox_to_anchor=(1.25, 0.8), ncol= 1)
plt.setp(L.texts, family='sans serif')
L.get_frame().set_facecolor('none')
L.get_texts()[2].set_text('Others')
L.get_texts()[3].set_text('')
L.get_texts()[4].set_text('')
L.get_texts()[5].set_text('')
ax.tick_params(axis='both', which='both',left=False, bottom=False,labelbottom=True)
plt.show()
I figure how to change the text on a label with: L.get_texts()[2].set_text('Others'), but can't find how to delete it, I would like a Legend with just 'Western Europe', 'Sub-Saharan Africa' and 'Other'.
I think that maybe with the 'handler_map', but I can't figure out how it works.
CodePudding user response:
The legend automatically ignores all labels that start with '_'.
An idea is to rename all grey regions to start with a '_'.
Your code is missing reproducible data, but the changes could look like:
df21['Regional indicator']
new_name = {month: '_' month if color == '#cccccc' else month for month, color in palette.items()}
new_name['North America and ANZ'] = 'other'
df21['Regional indicator'] = df21['Regional indicator'].map(new_names)
new_palette = {new_name[month]: color for month, color in palette.items()}
sns.scatterplot(data=df21, x='Healthy life expectancy', y='Ladder score',
hue='Regional indicator',
palette=new_palette, alpha=0.95, ec='black',
size=df21["Logged GDP per capita"] * 1000, legend=True, sizes=(5, 500))
Here is a self-contained example using seaborn's flights dataset.
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
flights = sns.load_dataset('flights')
palette = {'Jan': 'crimson', 'Feb': 'limegreen', 'Mar': 'blue', 'Apr': 'gold', 'May': 'purple', 'Jun': '#cccccc',
'Jul': '#cccccc', 'Aug': '#cccccc', 'Sep': '#cccccc', 'Oct': '#cccccc', 'Nov': '#cccccc', 'Dec': '#cccccc'}
new_name = {month: '_' month if color == '#cccccc' else month for month, color in palette.items()}
new_name['Jun'] = 'other'
flights['month'] = flights['month'].map(new_names)
new_palette = {new_name[month]: color for month, color in palette.items()}
sns.scatterplot(data=flights, x='year', y='passengers', hue='month', palette=new_palette)
plt.show()

