Наложение фактических данных на коробчатую диаграмму из фрейма данных pandas

Я использую Seaborn для создания коробчатых диаграмм из фреймов данных pandas. Seaborn boxplots, по-видимому, по существу считывают фреймы данных так же, как и pandas boxplot функциональность (так что я надеюсь, что решение одинаково для обоих, но я могу просто использовать функцию dataframe.boxplot). Мой фрейм данных состоит из 12 столбцов, и следующий код генерирует один график с одним блоком для каждого столбца (точно так же, как функция dataframe.boxplot()).

fig, ax = plt.subplots()
sns.set_style("darkgrid", {"axes.facecolor":"darkgrey"})
pal = sns.color_palette("husl",12)
sns.boxplot(dataframe, color = pal)

Может ли кто-нибудь предложить простой способ наложения всех значений (по столбцам) при создании коробчатой ​​диаграммы из фреймов данных? Буду признателен за любую помощь с этим.


person geog_newbie    schedule 12.04.2014    source источник


Ответы (3)


Общее решение для блочной диаграммы для всего фрейма данных, которое должно работать как для seaborn, так и для pandas, поскольку все они matplotlib находятся под капотом, я буду использовать график pandas в качестве примера, предполагая, что import matplotlib.pyplot as plt уже на месте. Поскольку у вас уже есть ax, было бы разумнее просто использовать ax.text(...) вместо plt.text(...).

In [35]:    
print df
         V1        V2        V3        V4        V5
0  0.895739  0.850580  0.307908  0.917853  0.047017
1  0.931968  0.284934  0.335696  0.153758  0.898149
2  0.405657  0.472525  0.958116  0.859716  0.067340
3  0.843003  0.224331  0.301219  0.000170  0.229840
4  0.634489  0.905062  0.857495  0.246697  0.983037
5  0.573692  0.951600  0.023633  0.292816  0.243963

[6 rows x 5 columns]

In [34]:    
df.boxplot()
for x, y, s in zip(np.repeat(np.arange(df.shape[1])+1, df.shape[0]), 
                   df.values.ravel(), df.values.astype('|S5').ravel()):
    plt.text(x,y,s,ha='center',va='center')

введите описание изображения здесь

Для одной серии в фрейме данных необходимо внести несколько небольших изменений:

In [35]:    
sub_df=df.V1
pd.DataFrame(sub_df).boxplot()
for x, y, s in zip(np.repeat(1, df.shape[0]), 
                   sub_df.ravel(), sub_df.values.astype('|S5').ravel()):
    plt.text(x,y,s,ha='center',va='center')

введите описание изображения здесь

Создание точечных диаграмм также аналогично:

#for the whole thing
df.boxplot()
plt.scatter(np.repeat(np.arange(df.shape[1])+1, df.shape[0]), df.values.ravel(), marker='+', alpha=0.5)
#for just one column
sub_df=df.V1
pd.DataFrame(sub_df).boxplot()
plt.scatter(np.repeat(1, df.shape[0]), sub_df.ravel(), marker='+', alpha=0.5)

введите описание изображения здесь введите описание изображения здесь

Чтобы наложить материал на boxplot, нам нужно сначала угадать, где каждый прямоугольник расположен среди xaxis. Похоже, они находятся на 1,2,3,4,..... Поэтому для значений в первом столбце мы хотим, чтобы они отображались на графике при x = 1; 2-й столбец при x = 2 и так далее.

Любой эффективный способ сделать это - использовать np.repeat, повторять 1,2,3,4..., каждое n раз, где n - количество наблюдений. Затем мы можем построить график, используя эти числа как x координаты. Поскольку он одномерный, для координат y нам понадобится плоское представление данных, предоставленное df.ravel()

Для наложения текстовых строк нам понадобится еще один шаг (цикл). Поскольку мы можем отображать только одно значение x, одно значение y и одну текстовую строку за раз.

person CT Zhu    schedule 12.04.2014
comment
Извините, фраза "фактические значения" сбивает с толку. Под этим я имел в виду своего рода диаграмму рассеяния, наложенную на коробчатую диаграмму, то есть с точками вместо числовых значений. Спасибо, что посмотрели на мой вопрос! - person geog_newbie; 13.04.2014
comment
Да, это сбивает с толку. См. Редактировать. Я предлагаю вам использовать разумное значение alpha, чтобы, если у вас много точек данных, вы могли лучше видеть «облако». Если вы хотите выглядеть модно, подумайте об этом nbviewer .ipython.org / github / mgymrek / pybeeswarm / blob / master / - person CT Zhu; 13.04.2014
comment
Да, это здорово. Спасибо за быстрый ответ, @CT Zhu! Это сработало как шарм. Должен признаться, мне придется еще раз взглянуть на решение, чтобы понять, что вы там сделали ... Мне нужно еще пару баллов, чтобы дать вам положительный голос. - person geog_newbie; 13.04.2014
comment
Нет проблем, с тех пор я написал еще несколько строк кода, на этот раз на English языке, на который вы можете смотреть. Ваше здоровье! - person CT Zhu; 13.04.2014
comment
@CTZhu Я хочу сделать что-то очень похожее на это, однако я использую dataframe.boxplot (by = 'column1'), эта группировка, похоже, не работает с вашим примером. есть ли у вас какие-либо предложения по этому поводу. По сути, мой прямоугольный график - это xaxis df [column1], yaxis df [column2], и я хотел бы построить график рассеяния поверх него. но с xticks, установленным на тексты, я смущен. Мне удалось найти xticks и xtick_labels, которые были установлены в бокс-графике. - person CRogers; 02.01.2016

Это еще не было добавлено в функцию seaborn.boxplot, но есть что-то похожее в seaborn.violinplot, в которой есть другие преимущества:

x = np.random.randn(30, 6)
sns.violinplot(x, inner="points")
sns.despine(trim=True)

введите описание изображения здесь

person mwaskom    schedule 13.04.2014

У меня есть такая хитрость:

data = np.random.randn(6,5)

df = pd.DataFrame(data,columns = list('ABCDE'))

Now assign a dummy column to df:
df['Group'] = 'A'

print df

          A         B         C         D         E Group
0  0.590600  0.226287  1.552091 -1.722084  0.459262     A
1  0.369391 -0.037151  0.136172 -0.772484  1.143328     A
2  1.147314 -0.883715 -0.444182 -1.294227  1.503786     A
3 -0.721351  0.358747  0.323395  0.165267 -1.412939     A
4 -1.757362 -0.271141  0.881554  1.229962  2.526487     A
5 -0.006882  1.503691  0.587047  0.142334  0.516781     A

Используйте df.groupby.boxplot(), вы сделаете это.

df.groupby('Group').boxplot()

Наложение прямоугольной диаграммы

person HP Peng    schedule 25.04.2016