如何使用 sharex=True 在 catplot (kind='violin') 顶部绘制 seaborn catplot (kind='count')

Ton*_*y A 4 python categorical-data seaborn

到目前为止我已经尝试过以下代码:

# 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()
Run Code Online (Sandbox Code Playgroud)

这似乎将每种类别的分类图分别堆叠在一起。 这似乎将每种类别的分类图分别堆叠在一起。

我想要的是以下代码在单个图中的结果图,其中第一行是计数图,第二行是小提琴图。

# 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)
Run Code Online (Sandbox Code Playgroud)

我想要跨越图中第一行的实际分类计数图,该图还包含分类小提琴图(参考图 3):
我想要跨越还包含分类小提琴图的图形的第一行的实际分类计数图(参考图 3)

我想要跨越图中第二行的实际分类小提琴图,该图还包含分类计数图(参考图 2):
我想要跨越图中第二行的实际分类小提琴图,该图还包含分类计数图(参考图 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])
Run Code Online (Sandbox Code Playgroud)

这张图片显示了将两个猫图强制到一个图上的黑客方法,它显示了我的实现的缺陷,因为标签、图例和其他孩子不会来乘坐/转移

Imp*_*est 5

通常不可能将多个seaborn图形级函数的输出组合成一个图形。请参阅(这个问题,也是这个问题)。我曾经写过一个 hack来外部组合这些数字,但它有几个缺点。如果它适合您,请随意使用它。

但一般来说,请考虑手动创建您想要的绘图。在这种情况下,它可能看起来像这样:

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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述