пропуск пустых фасетов в фасетной сетке seaborn для аннотаций

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

g.axes.flat имеет длину 9 (9 фасетов содержат данные); однако, когда я помещаю аннотацию к каждому элементу в g.axes.flat, она размещается не там, где я ожидал.

g = sns.FacetGrid(mapping, col=options.facetCol, row=options.facetRow, col_order=sorted(cols), hue=options.group, sharex=False)
g = g.map(sns.distplot, options.axis)

# label each facet with stats
grouped = mapping.groupby([options.facetRow, options.facetCol])
for ax, (name, df) in zip(g.axes.flat, grouped):
    df2 = df.groupby(options.group) # group by each thing that has its own color and run stats on it

    for i, (group, data) in enumerate(df2):
        x = data[options.axis]

        # calculate stats and create label
        n = len(x)
        mean = np.mean(x)
        std = np.std(x)
        label = r"%s: n=%s, $\mu$=%.2f $\sigma$=%.2f" %(group, n, mean, std)
        ax.annotate(label, xy=(0.05,0.9-(i*0.05)), xycoords='axes fraction', ha='left', size=8)

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

РЕДАКТИРОВАТЬ

Я создал функцию аннотации и передаю ее map() [как рекомендуется]; однако я не уверен, как передать имена меток в функцию и как заставить аннотации (по две для каждого аспекта) сдвигаться в направлении y. Есть еще предложения?

g = g.map(stats, options.axis)

def stats(x, **kwargs):
    ax = sns.distplot(x, **kwargs)

    # calculate stats and create label
    n = len(x)
    mean = np.mean(x)
    std = np.std(x)
    label = r"%s: n=%s, $\mu$=%.2f $\sigma$=%.2f" %('moo', n, mean, std) # temporary label, need to pass it through function
    i = 1 # temporary, needs to increment to shift annotations so they aren't on top of each other

    # create annotation
    ax.annotate(label, xy=(0.05,0.9-(i*0.05)), xycoords='axes fraction', ha='left', size=8)

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


person Constantino    schedule 01.07.2015    source источник
comment
Это скорее вопрос панд, чем морской; вам нужно перебрать все группы, а не только те, которые содержат данные. Но лучше всего было бы определить функцию, которая делает аннотацию, а затем передать ее g.map.   -  person mwaskom    schedule 02.07.2015
comment
Чтобы сместить аннотацию, немного хитрости, но я бы сделал что-то вроде y = .7 if ax.texts else .8. Я не уверен, что вы имеете в виду, передавая имена меток функции, но map передаст имя уровня оттенка параметру label.   -  person mwaskom    schedule 02.07.2015


Ответы (1)


Окончательное решение было:

g = sns.FacetGrid(mapping, col=options.facetCol, row=options.facetRow, col_order=sorted(cols), hue=options.group, sharex=False)
g.map(sns.distplot, options.axis)
g.map(stats, options.axis)

# custom function that allows us to create a distplot and add offset annotations to each facet that is not empty
def stats(x, label, **kwargs):

    # get a reference to the currently active axes
    ax = plt.gca()    

    # calculate stats and create label
    n = len(x)
    mean = np.mean(x)
    std = np.std(x)
    label = r"%s: n=%s, $\mu$=%.2f $\sigma$=%.2f" %(label, n, mean, std)

    # create annotation
    y = 0.9 - len(ax.texts) * 0.05
    ax.annotate(label, xy=(0.05,y), xycoords='axes fraction', ha='left', size=8)
person Constantino    schedule 02.07.2015
comment
Я отредактировал код, чтобы взять вызов distplot из stats и передать его непосредственно map, что делает код аннотации более общим. - person mwaskom; 02.07.2015
comment
Откуда в этом контексте появилось слово «топор»? Думаю, это должен быть объект Axes, но как его получить? Спасибо! - person nickos556; 02.09.2016
comment
Я позволю @mwaskom вмешаться, потому что я не уверен; тем временем исходный ответ находится здесь: stackoverflow.com/revisions/ - person Constantino; 07.09.2016