Настройка аннотации с помощью FacetGrid Seaborn


Я пытаюсь настроить некоторые фигуры с помощью модуля Seaborn в Python, но мне не удалось создать пользовательские метки или аннотации. У меня есть код, который генерирует следующий рисунок:

plot = sns.FacetGrid(data = data, col = 'bot', margin_titles = True).set_titles('Human', 'Bot')
bins = np.linspace(0, 2000, 15)
plot = plot.map(plt.hist, 'friends_count', color = 'black', lw = 0, bins = bins)
plot.set_axis_labels('Number Following', 'Count')
sns.despine(left = True, bottom = True)

Введите описание изображения здесь

Я хотел бы сделать две вещи: 1. замените метки коэффициентов по умолчанию, например "bot = 0.0", на значимый текст и 2. нарисуйте вертикальные линии на среднем числе, следующем для каждой категории.

Вот самодостаточный пример:

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

fake = pd.DataFrame({'val': [1, 2, 2, 3, 3, 2, 1, 1, 2, 3], 'group': [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]})
plot = sns.FacetGrid(data = fake, col = 'group', margin_titles = True).set_titles('zero', 'one')
plot = plot.map(plt.hist, 'val', color = 'black', lw = 0)
sns.despine(left = True, bottom = True)

Кто-нибудь знает как настроить FacetGrids?

1 8

1 ответ:

Несколько вещей о set_titles.

Во-первых, заголовки по умолчанию рисуются в методе FacetGrid.map, поэтому, если вы хотите изменить заголовки, вы должны вызвать set_titles после построения, иначе они будут перезаписаны.

Во-вторых, если вы посмотрите на строку docstring для метода, он не просто принимает произвольный список заголовков. Он позволяет изменить способ отображения заголовка с помощью переменной столбца name и value:
template : string
    Template for all titles with the formatting keys {col_var} and
    {col_name} (if using a `col` faceting variable) and/or {row_var}
    and {row_name} (if using a `row` faceting variable).

Таким образом, самый простой способ иметь " значимый текст " - это использование значимых данных в вашем фрейме данных. Возьмем этот пример со случайными данными:

df = pd.DataFrame({'val': np.random.randn(100),
                   'group': np.repeat([0, 1], 50)})

Если вы хотите, чтобы "группа" была zero и one, вы должны просто изменить этот столбец или сделать новый:

df["group"] = df["group"].map({0: "zero", 1; "one"})

Затем скажите, что вы не хотите иметь имя переменной в заголовке, правильным способом использования FacetGrid.set_titles будет

g = sns.FacetGrid(data=df, col='group')
g.map(plt.hist, 'val', color='black', lw=0)
g.set_titles('{col_name}')

некоторые гистограммы

Если вы не хотите изменять данные, которые вы строите, то вам придется установить атрибуты на осях matplotlib непосредственно, что-то вроде:

for ax, title in zip(g.axes.flat, ['zero', 'one']):
    ax.set_title(title)
Обратите внимание, что это менее предпочтительно по сравнению с приведенным выше методом, поскольку вы должны быть очень осторожны, чтобы убедиться, что порядок вашего списка правильный и что он не изменится, в то время как получение информации из самого фрейма данных будет гораздо более надежным.

Чтобы построить среднее значение, вам нужно создать небольшую функцию, которую можно передать в FacetGrid.map. Естьнесколько примеров того, как это сделать в учебнике. В этом деле, это довольно просто:

def vertical_mean_line(x, **kwargs):
    plt.axvline(x.mean(), **kwargs)

Тогда все, что вам нужно, это заново построить график:

g = sns.FacetGrid(data=df, col='group')
g.map(plt.hist, 'val', color='black', lw=0)
g.map(vertical_mean_line, 'val')
g.set_titles('{col_name}')

еще несколько гистограмм