我可以在pandas DataFrame中获得一个工资列的箱线图...
train.boxplot(column='PredictionError',by='Category',sym='')
...但是我无法弄清楚如何定义“类别”列上使用的索引顺序 - 我想根据另一个标准提供我自己的自定义顺序:
category_order_by_mean_salary = train.groupby('Category')['Salary'].mean().order().keys()
如何将自定义列顺序应用于boxplot列? (除了丑陋地使用前缀强制排序列名称之外)
'Category'是一个字符串列,包含27个不同的值:['Accounting & Finance Jobs','Admin Jobs',...,'Travel Jobs']
。因此可以使用pd.Categorical.from_array()
在检查时,限制在 pandas.tools.plotting.py:boxplot()
内,它会转换列对象而不允许排序:
我想我可以破解pandas boxplot()的自定义版本,或者进入对象的内部。并提交增强请求。
编辑:这个问题出现在熊猫~0.13之间,可能已被最近的(0.19 +?)版本淘汰,根据@ Cireo的最新答案。答案 0 :(得分:7)
如果没有一个有效的例子,很难说如何做到这一点。我的第一个猜测就是只添加一个包含所需订单的整数列。
一种简单,强力的方法是一次添加一个箱图。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(np.random.rand(37,4), columns=list('ABCD'))
columns_my_order = ['C', 'A', 'D', 'B']
fig, ax = plt.subplots()
for position, column in enumerate(columns_my_order):
ax.boxplot(df[column], positions=[position])
ax.set_xticks(range(position+1))
ax.set_xticklabels(columns_my_order)
ax.set_xlim(xmin=-0.5)
plt.show()
答案 1 :(得分:4)
实际上我遇到了同样的问题。我通过制作地图并重置xticklabels来解决它,代码如下:
df = pd.DataFrame({"A":["d","c","d","c",'d','c','a','c','a','c','a','c']})
df['val']=(np.random.rand(12))
df['B']=df['A'].replace({'d':'0','c':'1','a':'2'})
ax=df.boxplot(column='val',by='B')
ax.set_xticklabels(list('dca'))
答案 2 :(得分:2)
请注意,pandas现在可以创建分类列。如果您不介意在图表中显示所有列,或者适当地修剪它们,您可以执行以下操作:
http://pandas.pydata.org/pandas-docs/stable/categorical.html
df['Category'] = df['Category'].astype('category', ordered=True)
最近的大熊猫似乎也允许positions
从框架到轴一直通过。
答案 3 :(得分:2)
添加一个单独的答案,这可能是另一个问题 - 反馈得到了赞赏。
我想在groupby中添加自定义列顺序,这给我带来了很多问题。最后,我不得不避免尝试使用boxplot
对象中的groupby
,而是自己浏览每个子图,以提供明确的位置。
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame()
df['GroupBy'] = ['g1', 'g2', 'g3', 'g4'] * 6
df['PlotBy'] = [chr(ord('A') + i) for i in xrange(24)]
df['SortBy'] = list(reversed(range(24)))
df['Data'] = [i * 10 for i in xrange(24)]
# Note that this has no effect on the boxplot
df = df.sort_values(['GroupBy', 'SortBy'])
for group, info in df.groupby('GroupBy'):
print 'Group: %r\n%s\n' % (group, info)
# With the below, cannot use
# - sort data beforehand (not preserved, can't access in groupby)
# - categorical (not all present in every chart)
# - positional (different lengths and sort orders per group)
# df.groupby('GroupBy').boxplot(layout=(1, 5), column=['Data'], by=['PlotBy'])
fig, axes = plt.subplots(1, df.GroupBy.nunique(), sharey=True)
for ax, (g, d) in zip(axes, df.groupby('GroupBy')):
d.boxplot(column=['Data'], by=['PlotBy'], ax=ax, positions=d.index.values)
plt.show()
在我的最终代码中,确定位置甚至更多,因为每个sortby值都有多个数据点,我最终必须执行以下操作:
to_plot = data.sort_values([sort_col]).groupby(group_col)
for ax, (group, group_data) in zip(axes, to_plot):
# Use existing sorting
ordering = enumerate(group_data[sort_col].unique())
positions = [ind for val, ind in sorted((v, i) for (i, v) in ordering)]
ax = group_data.boxplot(column=[col], by=[plot_by], ax=ax, positions=positions)
答案 4 :(得分:2)
正如Cireo所指出的:
使用新的 positions = 属性:
df.boxplot(column=['Data'], by=['PlotBy'], positions=df.index.values)
我知道以前已经对此进行过修正,但是对于像我这样的新手来说,它还不够清晰/概括。
答案 5 :(得分:1)
如果您对箱线图中的默认列顺序不满意,可以通过在箱线图函数中设置 column 参数将其更改为特定的顺序。
检查以下两个示例:
np.random.seed(0)
df = pd.DataFrame(np.random.rand(37,4), columns=list('ABCD'))
##
plt.figure()
df.boxplot()
plt.title("default column order")
##
plt.figure()
df.boxplot(column=['C','A', 'D', 'B'])
plt.title("Specified column order")
答案 6 :(得分:0)
这听起来可能很愚蠢,但是许多情节允许您确定顺序。例如:
库和数据集
import seaborn as sns
df = sns.load_dataset('iris')
特定订单
p1=sns.boxplot(x='species', y='sepal_length', data=df, order=["virginica", "versicolor", "setosa"])
sns.plt.show()
答案 7 :(得分:0)
这可以通过应用分类顺序来解决。您可以自己决定排名。我将以一周中的几天为例。
将分类顺序提供给工作日
#List categorical variables in correct order
weekday = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
#Assign the above list to category ranking
wDays = pd.api.types.CategoricalDtype(ordered= True, categories=Weekday)
#Apply this to the specific column in DataFrame
df['Weekday'] = df['Weekday'].astype(wDays)
# Then generate your plot
plt.figure(figsize = [15, 10])
sns.boxplot(data = flights_samp, x = 'Weekday', y = 'Y Axis Variable', color = colour)