boxplot matplotlib с разделенной осью y - PullRequest
0 голосов
/ 12 мая 2018

Я хотел бы сделать квадратную диаграмму с данными, подобными этим

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 лет, я не понимаю, что здесь происходит не так.

1 Ответ

0 голосов
/ 13 мая 2018

Вы слишком усложняете это, код для разрушения оси 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)

Pandas boxplot

Конечно, вы также можете использовать коробочный график 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)

matplotlib boxplot

...