Matplotlib 将不含数据的类别添加到seaborn中的绘图中

Matplotlib 将不含数据的类别添加到seaborn中的绘图中,matplotlib,seaborn,Matplotlib,Seaborn,我正在将一些数据绘制为catplot,如下所示: 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

我正在将一些数据绘制为catplot,如下所示:

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轴上显示了样本1和样本3。但是想象一下,还有一个示例2,其中没有数据点。如何在x轴上显示1、2和3?

顺序参数 当然,人们需要知道预期的类别。给定预期类别的列表,可以使用
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()
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()

选择 上述内容适用于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 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()
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()
序参量 当然,人们需要知道预期的类别。给定预期类别的列表,可以使用
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()
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()

选择 上述内容适用于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 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()
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()

您是否介意解释一下“某些类别的‘VAF’不包含数据”在数据/代码方面的实际含义?还有,你指的是哪个标签?@ImportanceOfBeingErnest我添加了一个例子,希望能有所帮助。由于当前版本中存在一个小错误,答案比预期的要复杂一些。你介意解释一下“某些类别的‘VAF’不包含数据”在数据/代码方面的实际含义吗?还有,你指的是哪个标签?@ImportanceOfBeingErnest我添加了一个例子,希望能有所帮助。由于当前版本中存在一个小错误,答案比预期的要复杂一些。除了这个已经非常详细的答案之外,还有一个可能的补充——如果你将
'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中测试)除了这个已经非常详细的答案之外,还有一个可能的补充-如果您将
'Number'
列分类(即
df['Number']=pd.category(df['Number'],categories=['one','Two','Three'])
,那么您只需按照指定的方式进行绘图-
ax=sns.stripplot(x='Number',y='Data',jitter True,Data=df)
-根据需要添加类别(在matplotlib 2.1.0中测试)