在seaborn箱线图中隐藏未观察到的类别

3

我目前正在进行数据分析,并希望通过seaborn箱形图展示一些数据分布。

我的分类数据'seg1'在我的数据集中有3个取值('Z1'、'Z3'和'Z4')。然而,组'Z4'的数据对于我来说太奇异了,我想制作仅显示类别'Z1'和'Z3'的箱形图。

过滤绘图的数据源没有起作用,因为类别'Z4'仍然显示了没有数据点。

除了必须创建一个只包含('Z1'、'Z3')的新CategoricalDtype并将我的数据重新投射到这个新类别上之外,是否还有其他解决方案?

我只想隐藏'Z4'类别。

我正在使用seaborn 0.10.1和matplotlib 3.3.1。

谢谢您提前的回答。

以下是我的尝试和一些可重现的数据。

虚拟数据

dummy_cat = pd.CategoricalDtype(['a', 'b', 'c'])
df = pd.DataFrame({'col1': ['a', 'b', 'a', 'b'], 'col2': [12., 5., 3., 2]})
df.col1 = df.col1.astype(dummy_cat)
sns.boxplot(data=df, x='col1', y='col2')

虚拟数据

不应用任何过滤器

fig, axs = plt.subplots(figsize=(8, 25), nrows=len(indicators2), squeeze=False)
for j, indicator in enumerate(indicators2):
    sns.boxplot(data=orders, y=indicator, x='seg1', hue='origin2', ax=axs[j, 0], showfliers=False)

这会产生以下结果:

未过滤的数据

筛选数据源

mask_filter = orders.seg1.isin(['Z1', 'Z3'])

fig, axs = plt.subplots(figsize=(8, 25), nrows=len(indicators2), squeeze=False)
for j, indicator in enumerate(indicators2):
    sns.boxplot(data=orders.loc[mask_filter], y=indicator, x='seg1', hue='origin2', ax=axs[j, 0], showfliers=False)

这将产生:

过滤数据源


1
当我运行你的代码时,我得到了你想要的绘图,但没有“Z4”。你确定你正在运行最新版本的seaborn(0.10.1)吗? - JohanC
看起来我落后了几个版本,我正在使用 seaborn 0.8.1。升级到最新版本后,我将进行测试。 - Pierre Massé
我将seaborn库更新到0.10.1版本(matplotlib为3.3.1,因此是最新的),但我仍然遇到了这个问题。您确定在测试“seg1”时它是“CategoricalDtype”吗? - Pierre Massé
1
将列转换为字符串时可能会出现什么问题? df.col1 = df.col1.astype(str) - JohanC
您还可以重置 xlimax.set_xlim(-0.5, 1.5) - JohanC
谢谢您的建议@JohanC,通过将其简单转换为字符串确实起作用(尽管显然不会保留类别顺序,因为绘制的数据不再是分类数据)。我不知道这是否符合礼仪,但我会在下午发布这个建议作为答案,除非您先于我发布。 - Pierre Massé
1个回答

3

要截断最后一个(或第一个)x值,可以使用set_xlim(),例如:ax.set_xlim(-0.5, 1.5)

另一个选项是使用seaborn的order=参数,并仅在该列表中添加所需的值。可选地,可以通过编程方式创建:

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

dummy_cat = pd.CategoricalDtype(['a', 'b', 'c'])
df = pd.DataFrame({'col1': ['a', 'b', 'a', 'b'], 'col2': [12., 5., 3., 2]})
df.col1 = df.col1.astype(dummy_cat)
order = [cat for cat in dummy_cat.categories if df['col1'].str.contains(cat).any()]
sns.boxplot(data=df, x='col1', y='col2', order=order)
plt.show()

example plot


2
太棒了!我没有想到可以使用 order 参数来过滤掉不需要的类别。这还可以微调类别的顺序。我也以同样的方式使用了 hue_order 参数来过滤“色调”类别。非常感谢! - Pierre Massé

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接