Настройка легенды с помощью scatterplot - PullRequest
0 голосов
/ 31 января 2019

Я изо всех сил пытаюсь настроить легенду моего графика рассеяния.Вот снимок:

Fun with MatPlotLib

А вот пример кода:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]],
                     columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size="CI_CT")
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

Также я работаю в Jupyter-лабораторная записная книжка с Python 3, если это поможет.

Красная проблема

Прежде всего, я хочу скрыть имя переменной CI_CT (на рисунке обведено красным),Изучив всю документацию на этот день, я нашел метод get_legend_handlers_label (см. здесь ), который производит следующее:

>>> g.get_legend_handles_labels()
([<matplotlib.collections.PathCollection at 0xfaaba4a8>,
  <matplotlib.collections.PathCollection at 0xfaa3ff28>,
  <matplotlib.collections.PathCollection at 0xfaa3f6a0>,
  <matplotlib.collections.PathCollection at 0xfaa3fe48>],
  ['CI_CT', '0', '1', '2'])

Где я могу обнаружить моего дорогого CI_CTстрока.Однако я не могу изменить это имя или полностью его скрыть.Я нашел способ dirty , который в основном заключается в неэффективном использовании кадра данных, переданного как параметр data.Вот scatterplot вызов:

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size=my_df["CI_CT"].values)

Результат здесь:

First issue solved in a dirty way

Работает, но есть уборщик способ достижения этого?

Зеленая штуковина

Отображение уровня 0 в этой легенде неверно, поскольку в столбце * 1044 нет нулевого значенияmy_df.Поэтому это вводит в заблуждение читателей, которые могут предположить, что меньшие точки представляют значение 0 или 1. Я хочу установить определенный масштаб таким образом, как это можно сделать для осей x и y.Однако я не могу этого достичь.Любая идея?

TL; DR: более широкий вопрос, который может решить все

Эти приключения заставляют меня задуматься, есть ли способ обработки данных, которые можно передать на диаграммы рассеяния с помощью hueи size параметры в чистом виде по оси X и Y.Это действительно возможно?

Прошу прощения за мой английский, пожалуйста, дайте мне знать, если вопрос слишком широкий или неправильно помечен.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

«Проблема с зеленой вещью», а именно то, что существует еще одна запись легенды, чем есть размеры, решается путем указания legend="full".

g = sns.scatterplot(..., legend="full")

«Проблема с красной вещью» более сложная.Проблема здесь в том, что Seaborn использует заголовок обычной легенды как заголовок легенды.Опция действительно заключается в том, чтобы указывать значения напрямую, а не в имени столбца, чтобы запретить использовать имя этого столбца в seaborn.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]],
                     columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size=my_df["CI_CT"].values, legend="full")
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

plt.show()

enter image description here

Если вы действительно должны использовать само имя столбца, то вы должны найти полезную легенду и удалить ярлык, который вам не нужен.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]],
                     columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size="CI_CT", legend="full")
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

#Hack to remove the first legend entry (which is the undesired title)
vpacker = g.get_legend()._legend_handle_box.get_children()[0]
vpacker._children = vpacker.get_children()[1:]

plt.show()
0 голосов
/ 01 февраля 2019

Мне наконец-то удалось получить желаемый результат, но уродливый способ.Это может быть полезно для кого-то, но я бы не советовал делать это.

Решение для исправления масштаба в легенде состоит в перемещении всех значений столбца CI_CT в отрицательные значения (чтобы сохранить порядок ипостоянство размера маркеров).Затем значения, отображаемые в легенде, корректируются в соответствии с предыдущими изменениями данных (вдохновение от здесь ).

Однако я не нашел лучшего способа сделать текст "CI_CT"исчезнуть в легенде, не оставляя ужасно огромного пробела.

Вот пример кода и результат.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]], columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

# Substracting the maximal value of CI_CT for each value
max_val = my_df["CI_CT"].agg("max")
my_df["CI_CT"] = my_df.apply(lambda x : x["CI_CT"] - max_val, axis=1)

# scatterplot declaration
g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size=my_df["CI_CT"].values)
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

# Correcting legend values
l = g.legend_
for t in l.texts :
    t.set_text(int(t.get_text()) + max_val)

# Restoring the DF
my_df["CI_CT"] = my_df.apply(lambda x : x["CI_CT"] + max_val, axis=1)

Fancy yet badly produced scatterplot

Я все еще ищу лучший способ достичь этого.

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