Как построить сюжет для морской птицы (kind = 'count') поверх catplot (kind = 'violin') с помощью sharex = True - PullRequest
3 голосов
/ 17 марта 2019

Пока я пробовал следующий код:

# Import to handle plotting
import seaborn as sns

# Import pyplot, figures inline, set style, plot pairplot
import matplotlib.pyplot as plt

# Make the figure space
fig = plt.figure(figsize=(2,4))
gs = fig.add_gridspec(2, 4)
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, :])

# Load the example car crash dataset
tips = sns.load_dataset("tips")

# Plot the frequency counts grouped by time
sns.catplot(x='sex', hue='smoker',
                                   kind='count',
                                   col='time',
                                   data=tips,
                                   ax=ax1)

# View the data
sns.catplot(x='sex', y='total_bill', hue='smoker',
                                                   kind='violin',
                                                   col='time',
                                                   split='True', 
                                                   cut=0, 
                                                   bw=0.25, 
                                                   scale='area',
                                                   scale_hue=False,
                                                   inner='quartile',
                                                   data=tips,
                                                   ax=ax2)

plt.close(2)
plt.close(3)
plt.show()

Кажется, что это складывает категориальные графики, каждого вида, соответственно, поверх друг друга. This seems to stack the categorial plots, of each kind respectively, on top of eachother.

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

# Import to handle plotting
import seaborn as sns

# Import pyplot, figures inline, set style, plot pairplot
import matplotlib.pyplot as plt

# Load the example car crash dataset
tips = sns.load_dataset("tips")

# Plot the frequency counts grouped by time
sns.catplot(x='sex', hue='smoker',
                                   kind='count',
                                   col='time',
                                   data=tips)

# View the data
sns.catplot(x='sex', y='total_bill', hue='smoker',
                                                   kind='violin',
                                                   col='time',
                                                   split='True', 
                                                   cut=0, 
                                                   bw=0.25, 
                                                   scale='area',
                                                   scale_hue=False,
                                                   inner='quartile',
                                                   data=tips)

Фактический категориальный граф, который я хотел бы охватить первой строкой фигуры, которая также содержит категорический сюжет для скрипки (Ref. Image 3):
The actual categorical countplot that I would like to span row one of a figure that also contains a categorical violin plot (Ref. Image 3)

Фактический категорический сюжет для скрипки, который я хотел бы охватить второй строкой фигуры, которая также содержит категориальный граф (Ref. Image 2):
The actual categorical violin plot that I would like to span row two of a figure that also contains a categorical countplot (Ref. Image 2)

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

# Import to handle plotting
import seaborn as sns

# Import pyplot, figures inline, set style, plot pairplot
import matplotlib.pyplot as plt

# Set some style
sns.set_style("whitegrid")

# Load the example car crash dataset
tips = sns.load_dataset("tips")

# Plot the frequency counts grouped by time
a = sns.catplot(x='sex', hue='smoker',
                                       kind='count',
                                       col='time',
                                       data=tips)

numSubs_A = len(a.col_names)

for i in range(numSubs_A):
    for p in a.facet_axis(0,i).patches:
        a.facet_axis(0,i).annotate(str(p.get_height()), (p.get_x()+0.15, p.get_height()+0.1))

# View the data
b = sns.catplot(x='sex', y='total_bill', hue='smoker',
                                                       kind='violin',
                                                       col='time',
                                                       split='True', 
                                                       cut=0, 
                                                       bw=0.25, 
                                                       scale='area',
                                                       scale_hue=False,
                                                       inner='quartile',
                                                       data=tips)

numSubs_B = len(b.col_names)

# Subplots migration
f = plt.figure()
for i in range(numSubs_A):
    f._axstack.add(f._make_key(a.facet_axis(0,i)), a.facet_axis(0,i))
for i in range(numSubs_B):
    f._axstack.add(f._make_key(b.facet_axis(0,i)), b.facet_axis(0,i))

# Subplots size adjustment
f.axes[0].set_position([0,1,1,1])
f.axes[1].set_position([1,1,1,1])
f.axes[2].set_position([0,0,1,1])
f.axes[3].set_position([1,0,1,1])

This image shows the hack'd method of forcing both catplots onto a single plot, it shows the deficiency of my implementation in that the labels, legends, and other children aren't coming for the ride/transfer

Ответы [ 2 ]

2 голосов
/ 18 марта 2019

В общем случае невозможно объединить вывод нескольких функций уровня моря в одну фигуру. Смотрите ( этот вопрос , также этот вопрос ). Однажды я написал хак , чтобы внешне объединить такие цифры, но у него есть несколько недостатков. Не стесняйтесь использовать его, если он работает для вас.

Но, в общем, рассмотрите возможность создания желаемого сюжета вручную. В этом случае это может выглядеть так:

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

fig, axes = plt.subplots(2,2, figsize=(8,6), sharey="row", sharex="col")

tips = sns.load_dataset("tips")
order = tips["sex"].unique()
hue_order = tips["smoker"].unique()


for i, (n, grp) in enumerate(tips.groupby("time")):
    sns.countplot(x="sex", hue="smoker", data=grp, 
                  order=order, hue_order=hue_order, ax=axes[0,i])
    sns.violinplot(x='sex', y='total_bill', hue='smoker', data=grp,
                   order=order, hue_order=hue_order,
                   split='True', cut=0, bw=0.25, 
                   scale='area', scale_hue=False,  inner='quartile', 
                   ax=axes[1,i])
    axes[0,i].set_title(f"time = {n}")

axes[0,0].get_legend().remove()
axes[1,0].get_legend().remove()
axes[1,1].get_legend().remove()
plt.show()

enter image description here

0 голосов
/ 17 марта 2019

seaborn.catplot не принимает аргумент "топор", следовательно, проблема с вашим первым кодом.

Похоже, что для достижения желаемого x-общего доступа необходим некоторый взломдля:

Как построить несколько совместных участков Seaborn в субплоте

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

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