Построение фасетной гистограммы с использованием сводной статистики в Python

#python #bar-chart #seaborn

#python #столбчатая диаграмма #сиборн

Вопрос:

Есть ли краткий способ построения сводной статистики в Python в виде boxplot? Приведенный ниже код дает гистограмму каждого среднего значения, я хочу поменять каждую гистограмму на прямоугольную диаграмму.

Я понимаю, что мне не нужно подводить итоги, однако с реальными данными просто построение одного из блоков заняло много времени (даже с showfliers=False ); Мне не нужно видеть выбросы, и я также захочу добавить панель «по всему населению» (т. Е. По всем кластерам) для каждого «ПК» (любые предложения по этому поводу были бы с благодарностью.. Я снова пытаюсь перейти с R на python, и просто получение этих нескольких строк кода заняло достаточно много времени)

 import matplotlib.pyplot as plt
import seaborn as sns
out = pd.DataFrame({'cluster':['a']*100 ['b']*100,
                         'pc': ['w', 'x', 'y', 'z']*50,
                         'value': np.random.normal(size=200)})
grouped = out.groupby(['cluster', 'pc'])
out = grouped.describe()
out = out.reset_index()
out.columns = [e[0] if e[0] != 'value' else e[1] for e in out.columns.tolist()]

#sns.catplot(x='cluster', y='mean', col='pc', kind='bar', data=out)
g = sns.FacetGrid(out, col="pc", col_wrap = 2)
g = g.map(plt.bar, "cluster", "mean")
  

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

Ответ №1:

Вы можете нарисовать прямоугольную диаграмму из сводной статистики, используя Axes.bxp() . Это должно быть инкапсулировано в пользовательскую функцию построения графика, переданную map() :

 def my_bxp(**kwargs):
    ax = plt.gca()
    data = kwargs.pop('data')
    color = kwargs.pop('color')
    bxpstats = []
    for _,row in data.iterrows():
        print(row)
        d = {'med': row.loc['50%'],
             'q1': row.loc['25%'],
             'q3': row.loc['75%'],
             'whislo': row.loc['min'],
             'whishi': row.loc['max'],
             'label': row.loc['cluster']}
        bxpstats.append(d)
    ax.bxp(bxpstats, showfliers=False, boxprops=dict(color=color), 
                                       whiskerprops=dict(color=color), 
                                       capprops=dict(color=color))
    

g = sns.FacetGrid(out, col="pc", col_wrap = 2)
g = g.map_dataframe(my_bxp)
  

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

Обратите внимание, что для простоты у меня усы простираются от min до max, что не является обычным представлением. Возможно, вам придется вычислить правильные экстенты усов при расчете сводной статистики, если это то, что вы хотите.

Ответ №2:

Проще рисовать несколько боковых диаграмм с сохранением исходных данных.

 import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import random

df = pd.DataFrame({'cluster':['a']*100 ['b']*100,
                         'pc': ['w', 'x', 'y', 'z']*50,
                         'value': np.random.normal(size=200)})
c = ['a']*25 ['b']*25
df1 = pd.concat([pd.Series(c), 
           df[df['pc'] == 'w']['value'].reset_index(drop=True), 
           df[df['pc'] == 'x']['value'].reset_index(drop=True), 
           df[df['pc'] == 'y']['value'].reset_index(drop=True), 
           df[df['pc'] == 'z']['value'].reset_index(drop=True)], axis=1, ignore_index=True)
df1.columns = ['cluster','w','x','y','z']


fig, axes = plt.subplots(1, 4, figsize=(8, 4)
fig.subplots_adjust(wspace=0.3, hspace=0.4)

ax = sns.boxplot(x="cluster", y='w', data=df1, orient='v', ax=axes[0])
ax = sns.boxplot(x="cluster", y='x', data=df1, orient='v', ax=axes[1])
ax = sns.boxplot(x="cluster", y='y', data=df1, orient='v', ax=axes[2])
ax = sns.boxplot(x="cluster", y='z', data=df1, orient='v', ax=axes[3])
  

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

Комментарии:

1. Я пробовал это, но это заняло действительно много времени (я не стал ждать, пока это закончится).. Я могу предоставить подробную информацию об объеме данных и сроках в ближайшее время (как только я выполню срочную работу …).