Python 3.x 带分裂y轴的matplotlib箱线图

Python 3.x 带分裂y轴的matplotlib箱线图,python-3.x,matplotlib,boxplot,Python 3.x,Matplotlib,Boxplot,我想用类似的数据做一个方框图 d = {'Education': [1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4], 'Hours absent': [3, 100,5,7,2,128,4,6,7,1,2,118,2,4,136,1,1]} df = pd.DataFrame(data=d) df.head() 这样做很好: df.boxplot(column=['Hours absent'] , by=['Education']) plt.ylim(0, 140

我想用类似的数据做一个方框图

d = {'Education': [1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4], 
 'Hours absent': [3, 100,5,7,2,128,4,6,7,1,2,118,2,4,136,1,1]}
df = pd.DataFrame(data=d) 
df.head() 
这样做很好:

df.boxplot(column=['Hours absent'] , by=['Education'])
plt.ylim(0, 140)
plt.show()
但是异常值很遥远,因此我想分割y轴。 但是这里不再接受boxplot命令“column”和“by”。因此,我只得到一个合并的数据点,而不是按教育来分割数据。 这是我的代码:

dfnew = df[['Hours absent', 'Education']] # In reality I take the different 
columns from a much bigger dataset

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)

ax1.boxplot(dfnew['Hours absent'])
ax1.set_ylim(40, 140)

ax2.boxplot(dfnew['Hours absent'])
ax2.set_ylim(0, 40)

ax1.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)

ax1.xaxis.tick_top()
ax1.tick_params(labeltop='off')  # don't put tick labels at the top
ax2.xaxis.tick_bottom()

d = .015  # how big to make the diagonal lines in axes coordinates
# arguments to pass to plot, just so we don't keep repeating them
kwargs = dict(transform=ax1.transAxes, color='k', clip_on=False)
ax1.plot((-d, +d), (-d, +d), **kwargs)        # top-left diagonal
ax1.plot((1 - d, 1 + d), (-d, +d), **kwargs)  # top-right diagonal

kwargs.update(transform=ax2.transAxes)  # switch to the bottom axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs)  # bottom-left diagonal
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs)  # bottom-right diagonal

plt.show()
这些是我尝试过的事情(我总是在第一和第二个子批次中更改此项)和我得到的错误

ax1.boxplot(dfnew['Hours absent'],dfnew['Education']) 
#The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), 
#a.any() or a.all().
ax1.boxplot(column=dfnew['Hours absent'], by=dfnew['Education'])#boxplot() 
#got an unexpected keyword argument 'column'
ax1.boxplot(dfnew['Hours absent'], by=dfnew['Education']) #boxplot() got an 
#unexpected keyword argument 'by'
我还尝试将数据转换为y轴的数组和x轴的列表:

data = df[['Hours absent']].as_matrix()
labels= list(df['Education'])

print(labels)
print(len(data))
print(len(labels))

print(type(data))
print(type(labels))
我在plot命令中替换如下:

ax1.boxplot(x=data, labels=labels)
ax2.boxplot(x=data, labels=labels)
现在错误是ValueError:标签和X的尺寸必须兼容。
但是它们都是17长的,我不明白这里出了什么问题。

你把它复杂化了,破坏Y轴的代码独立于绘制箱线图的代码。没有什么能阻止您使用df.boxplot,它会添加一些您不想要的标签和标题,但这很容易修复

df.boxplot(column='Hours absent', by='Education', ax=ax1)
ax1.set_xlabel('')
ax1.set_ylim(ymin=90)

df.boxplot(column='Hours absent', by='Education', ax=ax2)
ax2.set_title('')
ax2.set_ylim(ymax=50)
fig.subplots_adjust(top=0.87)

当然,您也可以使用matplotlib的箱线图,只要提供所需的参数即可。根据它将生成的文档字符串

对于
x
的每一列或 序列
x

这意味着你必须自己做“单独”部分

grouper = df.groupby('Education')['Hours absent']
x = [grouper.get_group(k) for k in grouper.groups]

ax1.boxplot(x)
ax1.set_ylim(ymin=90)

ax2.boxplot(x)
ax2.set_ylim(ymax=50)

x的尺寸是(17,1),
标签的尺寸是(17,1)。也不要向函数抛出随机的关键字参数,它很少起作用,十分钟查看文档可以为您节省几个小时。但是如果
DataFrame.boxplot
适合您,为什么要切换到
Axes.boxplot
?@Goyo抱歉,我对python非常陌生。我使用axis.boxplot而不是df.boxplot,因为用于断开y轴的代码适用于此,但不适用于df.boxplot。现在我明白了,我不应该在axes.boxplots上使用df.boxplot关键字。谢谢你指出这一点!但是x和标签都是MatPlotLib.pyplot.boxplot和axes.boxplot的一部分。当我尝试使用数据和标签作为数组时,现在两者(17,1)都抛出了相同的ValueError。非常感谢你的帮助!非常感谢你!这是如此清晰和容易。但是我自己看着文件都没想到!再次感谢!实际上它不起作用。这与我在开始时尝试的非常相似,但您的两个版本都出现了错误(未定义名称“ax1”)。这里怎么了?我已加载numpy、pandas和matlotlib(%matplotlib inline)。我将jupyter笔记本电脑与python3一起使用。名称
ax1
必须在
fig(ax1,ax2)=plt.子批(2,1,sharex=True)
之后定义。这已经在你的代码中了。太棒了!对于一个刚刚起步的人来说,这并不是一件小事。我真的很感激你的病人和我在一起!非常感谢!