【问题标题】:Add a category without data in it to a plot in seaborn将一个没有数据的类别添加到 seaborn 的绘图中
【发布时间】:2019-06-22 00:55:55
【问题描述】:

我正在将一些数据绘制成这样的猫图:

ax = sns.catplot(x='Kind', y='VAF', hue='Sample', jitter=True, data=df, legend=False)

麻烦的是'VAF'的某些类别不包含数据,并且相应的标签没有添加到情节中。有没有办法保留标签但不为其绘制任何点?

这里有一个可重现的例子来帮助解释:

x=pd.DataFrame({'Data':[1,3,4,6,3,2],'Number':['One','One','One','One','Three','Three']})
plt.figure()
ax = sns.catplot(x='Number', y='Data', jitter=True, data=x)

在此图中,您可以看到在 x 轴上显示样本一和三。但是想象一下,还有一个样本 2,其中没有数据点。如何在 x 轴上显示一、二和三?

【问题讨论】:

  • 您介意解释一下“'VAF' 的某些类别不包含数据” 在数据/代码方面的实际含义吗?另外,你指的是哪个标签?
  • @ImportanceOfBeingErnest 我添加了一个希望有所帮助的示例。
  • 由于当前版本中的一个小错误,答案比预期的要复杂一些。

标签: matplotlib seaborn


【解决方案1】:

订单参数

当然,需要知道哪些类别是预期的。给定一个预期类别列表,可以使用order 参数来提供预期类别。

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

df = pd.DataFrame({'Data':[1,3,4,6,3,2],
                   'Number':['One','One','One','One','Three','Three']})

exp_cats = ["One", "Two", "Three"]

ax = sns.stripplot(x='Number', y='Data', jitter=True, data=df, order=exp_cats)

plt.show()

替代方案

以上内容适用于 matplotlib 2.2.3,但不适用于 3.0。它再次适用于当前的开发版本(因此为 3.1)。目前,有以下选择:

A.循环遍历类别

给定一个预期类别的列表,您可以遍历它们并绘制每个类别的散点图。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'Data':[1,3,4,6,3,2],
                   'Number':['One','One','One','One','Three','Three']})

exp_cats = ["One", "Two", "Three"]

for i, cat in enumerate(exp_cats):
    cdf = df[df["Number"] == cat]
    x = np.zeros(len(cdf))+i+.2*(np.random.rand(len(cdf))-0.5)
    plt.scatter(x, cdf["Data"].values)
plt.xticks(range(len(exp_cats)), exp_cats)

plt.show()

B.将类别映射到数字。

您可以将预期类别映射到数字并绘制数字而不是类别。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'Data':[1,3,4,6,3,2],
                   'Number':['One','One','One','One','Three','Three']})

exp_cats = ["One", "Two", "Three"]

df["IntNumber"] = df["Number"].map(dict(zip(exp_cats, range(len(exp_cats)))))

plt.scatter(df["IntNumber"] + .2*(np.random.rand(len(df))-0.5), df["Data"].values,
            c = df["IntNumber"].values.astype(int))
plt.xticks(range(len(exp_cats)), exp_cats)

plt.show()

C.将缺失的类别附加到数据框

最后,您可以将 nan 值附加到数据框中,以确保每个预期的类别都出现在其中。

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

df = pd.DataFrame({'Data':[1,3,4,6,3,2],
                   'Number':['One','One','One','One','Three','Three']})

exp_cats = ["One", "Two", "Three"]

dfa = df.append(pd.DataFrame({'Data':[np.nan]*len(exp_cats), 'Number':exp_cats}))

ax = sns.stripplot(x='Number', y='Data', jitter=True, data=dfa, order=exp_cats)

plt.show()

【讨论】:

  • 这个已经非常详细的答案的一个可能补充 - 如果您将'Number' 列设为分类(即df['Number'] = pd.Categorical(df['Number'], categories=['One', 'Two', 'Three'])),那么您可以简单地按照指定的方式进行绘图 - ax = sns.stripplot(x='Number', y='Data', jitter=True, data=df) - 使用类别根据需要添加
  • (在 matplotlib 2.1.0 中测试)
猜你喜欢
  • 2019-01-19
  • 1970-01-01
  • 2016-12-30
  • 2021-12-31
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多