Наложить два морских фактора - PullRequest
0 голосов
/ 27 апреля 2018

У меня трудности с наложением (наложением) двух фактор-участков с использованием библиотеки seaborn.

Общая проблема заключается в том, что я хотел бы изобразить тонкими серыми линиями все (фоновые данные), а затем сверху разноцветными, более толстыми линиями данные, которые мы хотим выделить. С одной стороны, мне не удается объединить два набора данных на графике с FacetGrid, а во-вторых, у меня проблема с использованием zorder.

Я сделал фиктивный пример с набором данных exercise:

sns.set_style('whitegrid')
exercise = sns.load_dataset("exercise")
background = exercise.assign(idkind = lambda df: df['id'].astype(str)+df.kind.astype(str))
foreground = exercise.groupby(['kind','time']).mean().reset_index().rename(columns={'id':'idkind'})

Пока я пытался:

  1. factorplot + factorplot

Построение двух factorplot с, как если бы оно было sns.pointplot дважды аналогично в этом примере . Мне нужно sns.factorplot из-за экспериментальной установки данных. Это не работает, так как создаются просто два независимых графика. Я бы в основном хотел, чтобы нижний график находился поверх верхнего.

g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', legend=False,color='lightgrey',data=background)
sns.factorplot(x="time", y="pulse", hue="kind", data=foreground)

enter image description here

  1. factorplot + gmap.(factorplot)

Таким образом, я попытался использовать sns.factorplot, который, я думаю, выдает FacetGrid и g.map в секунду sns.factorplot сверху, используя новый набор данных с точно таким же дизайном и категориями. В результате вместо использования одних и тех же подзаговоров создается ряд строк с повторным графиком.

g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', legend=False,color='lightgrey',data=background)
g.map(sns.factorplot, x="time", y="pulse",hue='idkind', col='kind', data=foreground)

enter image description here

  1. factorplot + g.map(pointplot)

g.map точечный график, который помещает весь набор данных во все вспомогательные участки, не учитывая дизайн FacetGrid.

g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', legend=False,color='lightgrey',data=background)
g.map(sns.pointplot,x="time", y="pulse", hue='idkind', col='kind', data=foreground,zorder='1000')

enter image description here

1 Ответ

0 голосов
/ 27 апреля 2018

Следует отметить, что каждый вызов factorplot создает свою фигуру. Таким образом, в целом, если цель состоит в том, чтобы иметь одну цифру, вы не можете вызывать factorplot более одного раза. Это объясняет, почему 1. и 2. просто не могут работать.

Для 3. это было бы моей первой попыткой (за исключением того, что zorder, скорее всего, должен быть числом, а не строкой).
Однако кажется, что zorder игнорируется или, по крайней мере, неправильно передается базовым функциям matplotlib.

Один из вариантов - установить zorder вручную. Следующее просматривает всех художников фоновых графиков и устанавливает их zorder в 1. Он также сохраняет этих художников в списке. После создания сюжета переднего плана можно снова просмотреть всех исполнителей и установить для zorder более высокие значения для тех исполнителей, которых нет в ранее сохраненном списке.

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

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_style('whitegrid')
exercise = sns.load_dataset("exercise")
background = exercise.assign(idkind = lambda df: df['id'] \
                            .astype(str)+df.kind.astype(str))

g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', 
                 legend=False,color='lightgrey',data=background)

backgroundartists = []
for ax in g.axes.flat:
    for l in ax.lines + ax.collections:
        l.set_zorder(1)
        backgroundartists.append(l)

g.map(sns.pointplot, "time", "pulse")

for ax in g.axes.flat:
    for l in ax.lines + ax.collections:
        if l not in backgroundartists:
            l.set_zorder(5)

plt.show()

enter image description here

...