Легенда Seaborn не соответствует линиям графика

Вопрос или проблема

У меня есть следующий код:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

v_exponents = range(2, 9)
vs = [2 ** exponent - 1 for exponent in v_exponents]
df = pd.read_csv('data/out/erdos_renyi_graph/path_lengths_dfs/stats.csv')
for v in vs:
    df_filtered = df[df['V'] == v]
    print(df_filtered)
    sns.lineplot(data=df_filtered, x="E", y="fraction_connected")
plt.legend(title="V", labels=vs)
plt.savefig(f'src/main/python/erdos_renyi_graph/path_lengths_dfs/doc/img/ErdosRenyiGraph-PathLengthsDFS.png')

Это дает такой вывод:

График Seaborn

Почему легенда испорчена? Есть чередующиеся тонкие и толстые линии, по две каждого цвета. Более того, не отображаются все цвета, только от синего до красного.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

v_exponents = range(2, 9)
vs = [2 ** exponent - 1 for exponent in v_exponents]
df = pd.read_csv('data/out/erdos_renyi_graph/path_lengths_dfs/stats.csv')
labels = []
fig, ax = plt.subplots()
for v in vs:
    df_filtered = df[df['V'] == v]
    print(df_filtered)
    sns.lineplot(data=df_filtered, x="E", y="fraction_connected", label=v)
handles, labels = ax.get_legend_handles_labels()

# Создать одну легенду
ax.legend(handles, labels)

plt.savefig(f'src/main/python/erdos_renyi_graph/path_lengths_dfs/doc/img/ErdosRenyiGraph-PathLengthsDFS.png')

.

Ответ или решение

Проблема, о которой вы упомянули, заключается в том, что легенда вашего графика соответствует не всем линиям на графике и отображается некорректно. Давайте подробно рассмотрим, почему это происходит и как можно исправить данную ситуацию.

Причины проблемы

  1. Многократный вызов sns.lineplot: В вашем первом блоке кода, каждый раз, когда вы вызываете sns.lineplot, вы не указываете явно метку (label) для каждой линии. Это приводит к тому, что для всех линий, добавляемых на график, создаются разные объекты line, и в итоге в легенде отображаются только последние добавленные линии. Кроме того, plt.legend() пытается создать легенду на основании линий, но поскольку они все с одинаковым цветом, это создает путаницу.

  2. Отсутствие корректной обработки объектов осей: Легенда генерируется на основе объектов, созданных на текущих осях. Если вы вызываете plt.legend() без явного указания объектов оси (например, используя ax.get_legend_handles_labels()), это может привести к неочевидным результатам.

Решения

Чтобы устранить указанную вами проблему, следует внести некоторые изменения в код. Рассмотрим обновленный фрагмент кода:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Определяем диапазон значений V
v_exponents = range(2, 9)
vs = [2 ** exponent - 1 for exponent in v_exponents]

# Загружаем данные
df = pd.read_csv('data/out/erdos_renyi_graph/path_lengths_dfs/stats.csv')

# Создаем объект фигуры и осей
fig, ax = plt.subplots()

# Проходим по каждому значению V и строим линии
for v in vs:
    df_filtered = df[df['V'] == v]
    sns.lineplot(data=df_filtered, x="E", y="fraction_connected", ax=ax, label=str(v))

# Получаем обработки и метки для легенды
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels, title="V")

# Сохраняем график
plt.savefig(f'src/main/python/erdos_renyi_graph/path_lengths_dfs/doc/img/ErdosRenyiGraph-PathLengthsDFS.png')

Объяснение изменений

  1. Добавление меток в lineplot: В строке sns.lineplot(...), мы добавили параметр label=str(v), который гарантирует, что каждая линия получит свою уникальную метку, соответствующую значению V.

  2. Работа с объектом осей: Мы используем аргумент ax=ax в sns.lineplot, чтобы убедиться, что все линии добавляются на один и тот же объект осей. Это помогает централизовать управляемые элементы графика и делает их более управляемыми.

  3. Создание легенды на основе объектов осей: Команда handles, labels = ax.get_legend_handles_labels() позволяет корректно получить все сохраненные ручки и метки из объекта осей, что будет гарантировать, что все линии будут правильно отображены в легенде.

Заключение

С применением этих изменений вы получите корректную легенду, соответствующую всем линиям на графике. Если у вас есть еще вопросы по конкретным аспектам, не стесняйтесь их задавать.

Оцените материал
Добавить комментарий

Капча загружается...