Как адаптировать слишком большие размеры точек в легенде о точечной диаграмме моря? - PullRequest
0 голосов
/ 27 марта 2020

Я создал серию пузырьковых сюжетов с seaborn, выглядит отлично, за исключением легенды: enter image description here

Я использовал следующую команду для создания этого графика:

ax = sns.scatterplot(x='year', y='population', hue='Country', data=temp,
                     size="density", sizes=(1500, 5000), alpha=0.25, palette="muted")

Как я могу удалить страну из легенды и оставить только плотность? В документации нет такой опции. Кроме того, как я могу приблизить значения в пузырьках и сделать их более заметными?

Runnable code:

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)
for line in temp.index:
    ax.text(temp.year[line], temp.population[line], temp.Country[line], horizontalalignment='center', size='medium', color='black', weight='semibold')
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
ax.set_ylabel("")
ax.set_xlabel("")
ax.set_title("Population density in 5 closely populated countries")

1 Ответ

2 голосов
/ 27 марта 2020

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()

resulting plot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...