简体   繁体   中英

Seaborn: How to add a new point with a new legend

Now I am handing the example problem:

people = [['PeopleA', 157.7, 55.8, 22.4, 'A'],
          ['PeopleB', 163.9, 100.2, 37.3, 'B'],
          ['PeopleC', 188.4, 75, 21.1, 'A'],
         ]

peopleBasedline = [['BaseLine', 178, 70]]
  
peopledf = pd.DataFrame(people, columns=['ID', 'Height', 'Weight', 'BMI', 'type'])
peoplebaseDf = pd.DataFrame(peopleBased, columns=['ID', 'Height', 'Weight'])
peopledf, peoplebaseDf

And draw the figure by using:

plt.figure(figsize=(12, 9))
sns.set(style="darkgrid")
sns.color_palette("mako", as_cmap=True)
# sns.figure(size=(20, 20))

axes = sns.scatterplot(
    data = peopledf, x="Height", y="Weight", hue="ID", size="BMI", sizes=(50, 500), legend="auto")

# sns.pointplot(x = "sex", y = "total_bill", ax=axes) 

# Legend split and place outside #
num_of_colors   = len(peopledf['ID'].unique()) + 1
handles, labels = axes.get_legend_handles_labels()
color_hl = handles[:num_of_colors], labels[:num_of_colors]
sizes_hl = handles[num_of_colors:], labels[num_of_colors:]


# Call legend twice #
color_leg = axes.legend(*color_hl,
                        bbox_to_anchor = (1.03, 1),
                        loc            = 'upper left',
                        borderaxespad  = 0.)
sizes_leg = axes.legend(*sizes_hl,
                        bbox_to_anchor = (1.33, 1),
                        loc            = 'upper left',
                        borderaxespad  = 0.)

# We need this because the 2nd call to legend() erases the first #
axes.add_artist(color_leg)

# Adjust #
plt.subplots_adjust(right=0.75)

And I can get the figure like this:

在此处输入图像描述

But if I want to add "peopleBasedline" into the figure like this (But don't care the size of the square): 在此处输入图像描述

Then how can I change my code?

Really thanks for your help.

Add a second graph to axes and add a new custom legend. The custom legend is added in a patch. I also make the height and width the same and make the legend similar to the second marker.

from matplotlib.patches import Patch

axes = sns.scatterplot(data=peopledf, x="Height", y="Weight", hue="ID", size="BMI", sizes=(50, 500), legend="auto")
sns.scatterplot(data=peoplebaseDf, x="Height", y="Weight", marker='s', s=200, color='0.2', ax=axes)

# Legend split and place outside #
num_of_colors   = len(peopledf['ID'].unique()) + 1
handles, labels = axes.get_legend_handles_labels()
color_hl = handles[:num_of_colors], labels[:num_of_colors]
sizes_hl = handles[num_of_colors:], labels[num_of_colors:]

# add legend
base_elements = [Patch(facecolor='k', edgecolor='k', label='Base line')]

# Call legend twice #
color_leg = axes.legend(*color_hl,
                        bbox_to_anchor = (1.03, 1),
                        loc            = 'upper left',
                        borderaxespad  = 0.)
sizes_leg = axes.legend(*sizes_hl,
                        bbox_to_anchor = (1.33, 1),
                        loc            = 'upper left',
                        borderaxespad  = 0.)
base_leg = axes.legend(handles=base_elements,
                       handlelength=1.4,
                       handleheight=1.4,
                        bbox_to_anchor = (1.03, 0.5),
                        loc            = 'upper left',
                        borderaxespad  = 0.)

# We need this because the 2nd call to legend() erases the first #
axes.add_artist(color_leg)
axes.add_artist(sizes_leg)
axes.add_artist(base_leg)

# Adjust #
plt.subplots_adjust(right=0.75)
plt.show()

在此处输入图像描述

Try adding a new axes.legend() but change the coordinates of the bbox_to_anchor . This should make a new legend box.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM