我一直遇到一个经常出现的问题,即使用seaborn的“分类”绘图功能来实际绘制分类数据的速率。
我在这里制作了一个简单的例子,我可以发誓曾经与seaborn合作过。我设法找到使用虚拟变量的解决方法,但这并不总是方便。有谁知道为什么我的“版本2”用于barplot的用例不起作用?
import pandas as pd
from pandas import DataFrame
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# Generate some example data of labels and associated values
outcomes = ['A' for _ in range(50)] + \
['B' for _ in range(20)] + \
['C' for _ in range(5)]
trial = range(len(outcomes))
df = DataFrame({'Trial': trial, 'Outcome': outcomes})
plt.close('all')
# Version 1: This works but is a non-ideal workaround
# Generate separate boolean columns for each outcome
df2 = pd.get_dummies(df.Outcome).astype(bool)
plt.figure()
sns.barplot(data=df2, estimator=lambda x: 100 * np.mean(x))
plt.title('Outcomes V1')
plt.ylabel('Percent Trials')
plt.ylim([0,100])
plt.show()
# Version 2: This doesn't work and results in the following error
# unsupported operand type(s) for /: 'str' and 'int'
plt.figure()
sns.barplot(x='Outcome', data=df, estimator=lambda x: 100 * np.mean(x))
plt.title('Outcomes V2')
plt.ylabel('Percent Trials')
plt.ylim([0,100])
plt.show()
答案 0 :(得分:0)
添加y
参数对您有用:
sns.barplot(x='Outcome', y='Trial', data=df, estimator=lambda x: 100 * np.mean(x))
但是,在您的情况下,使用sns.countplot
绘图更有意义(因为您希望将试验10视为一次出现,而不是实际的十次):
sns.countplot(x='Outcome', data=df)
如果你想要百分比,你可以这样做:
sns.barplot(x='Outcome', y='Trial', data=df, estimator=lambda x: len(x) / len(df) * 100)
使用宽格式数据框(例如df2
),您只能将数据框传递给data
参数,Seaborn将自动沿x轴绘制每个数字列。< / p>
使用长格式数据框(例如df
),您需要将参数传递给x
和y
参数。
来自sns.barplot
docstring(已添加):
输入数据可以以多种格式传递,包括:
- 表示为列表,numpy数组或pandas系列的数据向量 对象直接传递给
x
,y
和/或hue
参数。- “长格式”DataFrame,在这种情况下,
x
,y
和hue
变量将决定数据的绘制方式。- “宽格式”DataFrame,以便绘制每个数字列。
plt.boxplot
接受的任何内容(例如,二维数组或向量列表)