ax.get_legend_handles_labels()
получает текущие маркеры и метки для легенды. Это просто списки, которые можно сократить с помощью нарезки. Ручки, чтобы показать размеры слишком велики, чтобы вписаться в легенду. Просто получите размеры, масштабируйте их и установите их обратно. (Обратите внимание, что handles[i].get_sizes()
возвращает список, обычно с одной записью.)
Метки - это просто строки. При необходимости они могут быть созданы снова, например, с другим форматированием. Чтобы изменить количество отображаемых цифр, метка может быть сначала преобразована в плавающее, а затем обратно в строку f{float(label):.2f}'
(для форматирования используется f-строки ). Обратите внимание, что самой первой меткой является заголовок, который должен обрабатываться по-разному.
По желанию, ylimits могут быть расширены, потому что заполнение по умолчанию не учитывает большие точки разброса. Кроме того, текст может быть центрирован по вертикали, чтобы лучше вписаться в круги.
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
temp = pd.DataFrame({'year': [1980, 1980, 1980, 1980, 1980],
'population': [2.87, 2.95, 3.45, 4.18, 4.67],
'Country': ['ALB', 'ARM', 'URY', 'PAN', 'CAF'],
'density': [1.0, 1.03, 1.2, 1.46, 1.63]})
ax = sns.scatterplot(x='year', y='population', hue='Country', data=temp,
size="density", sizes=(500, 1500), alpha=0.25, palette="muted")
ax.set_xlim(1950, 2030)
ylim0, ylim1 = ax.get_ylim()
ydelta = (ylim1 - ylim0) * 0.05
ax.set_ylim(ylim0 - ydelta, ylim1 + ydelta)
for line in temp.index:
ax.text(temp.year[line], temp.population[line], temp.Country[line], ha='center', va='center', size='medium',
color='black', weight='semibold')
handles, labels = ax.get_legend_handles_labels()
entries_to_skip = len(temp) + 1
handles = handles[entries_to_skip:]
labels = labels[entries_to_skip:]
for h in handles[1:]:
sizes = [s / 10 for s in h.get_sizes()]
h.set_sizes(sizes)
labels = labels[:1] + [f'{float(lab):.2f}' for lab in labels[1:]]
plt.legend(handles, labels, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
ax.set_ylabel("")
ax.set_xlabel("")
plt.tight_layout()
plt.show()