Как превратить groupby() и value_counts() в несколько круговых / столбчатых диаграмм

#python #matplotlib

#python #панды #matplotlib #pandas-groupby #seaborn

Вопрос:

Предположим, у меня есть фрейм данных, и я просматриваю 2 его столбца (2 серии).

Используя один из столбцов — "no_employees" ниже — Может кто-нибудь любезно помочь мне выяснить, как создать 6 разных круговых диаграмм или столбчатых диаграмм (по 1 для каждой группы no_employees), которые иллюстрируют значения для значений «Да» / «Нет» в столбце «Обработка»? Я буду использовать matplotlib или seaborn , как вам кажется, проще всего.

Я использую прилагаемую строку кода для генерации кода ниже.

 dataframe_title.groupby(['no_employees']).treatment.value_counts(). 
 

Но теперь я застрял. Использую ли я seaborn ? .plot ? Кажется, что это должно быть легко, и я знаю, что есть некоторые случаи, когда я могу сделать subplots=True , но я действительно в замешательстве. Большое вам спасибо.

 no_employees    treatment
1-5             Yes           88
                No            71
100-500         Yes           95
                No            80
26-100          Yes          149
                No           139
500-1000        No            33
                Yes           27
6-25            No           162
                Yes          127
More than 1000  Yes          146
                No           135
 

Ответ №1:

Важность кодирования данных:

  1. Цель визуализации данных — упростить передачу информации (например, в данном случае, относительное количество 'treatments' для каждой категории)
  2. Столбчатая диаграмма позволяет легко отображать важную информацию
    • сколько в каждой группе сказали 'Yes' или 'No'
    • относительные размеры каждой группы
  3. Круговой график чаще используется для отображения выборки, где группы в выборке суммируются до 100%.
    • Википедия: Круговая диаграмма
      • Исследования показали, что сравнение по углу менее точное, чем сравнение по длине, поскольку люди менее способны различать различия.
      • Статистики обычно считают круговые диаграммы плохим методом отображения информации, и они редко встречаются в научной литературе.
    • Эти данные плохо представлены круговой диаграммой, поскольку каждый размер компании представляет собой отдельную совокупность, для правильного представления которой потребуется 6 круговых диаграмм.
    • Данные могут быть помещены в круговой график, как показали другие, но это не значит, что так и должно быть.
  • Независимо от типа графика, данные должны иметь правильную форму для API-интерфейса plot.
  • Проверено с pandas 1.3.0 помощью , seaborn 0.11.1 , и matplotlib 3.4.2

Настройка тестового фрейма данных

 import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np  # for sample data only

np.random.seed(365)
cats = ['1-5', '6-25', '26-100', '100-500', '500-1000', '>1000']

data = {'no_employees': np.random.choice(cats, size=(1000,)),
        'treatment': np.random.choice(['Yes', 'No'], size=(1000,))}

df = pd.DataFrame(data)

# set a categorical order for the x-axis to be ordered
df.no_employees = pd.Categorical(df.no_employees, categories=cats, ordered=True)

  no_employees treatment
0       26-100        No
1          1-5       Yes
2        >1000        No
3      100-500       Yes
4     500-1000       Yes
 

Построение графиков с pandas.DataFrame.plot() :

  • Для этого требуется группировать фрейм данных для получения .value_counts и разархивировать pandas.DataFrame.unstack .
 # to get the dataframe in the correct shape, unstack the groupby result
dfu = df.groupby(['no_employees']).treatment.value_counts().unstack()

treatment     No  Yes
no_employees         
1-5           78   72
6-25          83   86
26-100        83   76
100-500       91   84
500-1000      78   83
>1000         95   91

# plot
ax = dfu.plot(kind='bar', figsize=(7, 5), xlabel='Number of Employees in Company', ylabel='Count', rot=0)
ax.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
 

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


Построение графиков с seaborn

  • seaborn — это высокоуровневый API для matplotlib.

seaborn.barplot()

  • Требуется фрейм данных в аккуратном (длинном) формате, что выполняется путем группировки фрейма данных для получения .value_counts и сброса индекса с помощью pandas.Series.reset_index
  • Также может быть выполнено с помощью интерфейса уровня рисунка с помощью sns.catplot() with kind='bar'
 # groupby, get value_counts, and reset the index
dft = df.groupby(['no_employees']).treatment.value_counts().reset_index(name='Count')

   no_employees treatment  Count
0           1-5        No     78
1           1-5       Yes     72
2          6-25       Yes     86
3          6-25        No     83
4        26-100        No     83
5        26-100       Yes     76
6       100-500        No     91
7       100-500       Yes     84
8      500-1000       Yes     83
9      500-1000        No     78
10        >1000        No     95
11        >1000       Yes     91

# plot
p = sns.barplot(x='no_employees', y='Count', data=dft, hue='treatment')
p.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
p.set(xlabel='Number of Employees in Company')
 

seaborn.countplot()

  • Использует исходный фрейм данных, df , без каких-либо преобразований.
  • Также может быть выполнено с помощью интерфейса уровня рисунка с помощью sns.catplot() with kind='count'
 p = sns.countplot(data=df, x='no_employees', hue='treatment')
p.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
p.set(xlabel='Number of Employees in Company')
 
  • Вывод barplot и countplot

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

Ответ №2:

Давайте изменим структуру данных и построим график с помощью subplots=True:

 df_chart = df1.unstack()['Pct'] 

axs = df_chart.plot.pie(subplots=True, figsize=(4,9), layout=(2,1), legend=False, title=df_chart.columns.tolist())
ax_flat = axs.flatten()
for ax in ax_flat:
    ax.yaxis.label.set_visible(False)
 

Вывод:

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