Home > Enterprise >  How to rename labels and title in seaborn scatterplot legend?
How to rename labels and title in seaborn scatterplot legend?

Time:03-24

I have the following legend that I'd like to change:

enter image description here

I'd like to change the titles from State to Place and Transition to Kilometers and the labels underneath State need to change from 0 to City, 1 to Rural, and 2 to Other. I'd also like to change Transition values to integers instead of floats. Furthermore, I'd like to have the new titles in bold and oriented to the left side instead of right above the values.

I am not sure if all this is even possible and how to best go about this...

I obtained this legend by running the following code (bear in mind that this plot is part of ax2):

sns.scatterplot(data = data, x = 'x', y = 'y', size = 'Transition', hue = 'State', palette = 'flare', ax = ax2, legend = 'full')
ax2.legend(bbox_to_anchor = (1.05, 1), loc = 2, borderaxespad = 0)

CodePudding user response:

It's simplest to alter data with the desired values: map the places and convert the kilometers with astype.

If you prefer to keep data intact, assign the changes inside the plot call:

places = {0: 'City', 1: 'Rural', 2: 'Other'}

sns.scatterplot(data=data.assign(Place=data['State'].map(places), Kilometers=data['Transition'].astype(int)),
                x='x', y='y', size='Kilometers', hue='Place', palette='flare', ax=ax2, legend='full')

Or you can make the changes in-place beforehand:

data = data.rename(columns={'State': 'Place', 'Transition': 'Kilometers'})
data['Place'] = data['Place'].map({0: 'City', 1: 'Rural', 2: 'Other'})
data['Kilometers'] = data['Kilometers'].astype(int)

sns.scatterplot(data=data, x='x', y='y', size='Kilometers', hue='Place', palette='flare', ax=ax2, legend='full')

What about making the legend titles (Place and Kilometers) bold and slightly larger, and also maybe leftward shifted?

It seems seaborn reconstructs the legend manually, so those titles are not true title objects. I'm not sure if there's a better way, but you can replace your current ax2.legend(...) call with something like this:

# first remove the line: ax2.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0)

# then get the existing seaborn legend and alter it
leg2 = ax2.get_legend()
leg2.set_bbox_to_anchor((1.05, 1))
for t in leg2.get_texts():
    if t.get_text() in ['Place', 'Kilometers']:
        t.set_weight('bold')
        t.set_fontsize('large')
  • Related