Matplotlib Stackplot подсчетов по группам

#python #pandas #list #dictionary #matplotlib

#python #панды #Список #словарь #matplotlib

Вопрос:

Я полный новичок в Python и до сих пор совершенно не понимаю, как хранить данные для построения графика. Я пытаюсь создать график подсчетов по групповой переменной (континент) и переменной x (year_join). Вот пример данных, иллюстрирующих структуру

  df = pd.DataFrame({'id': ['1', '2', '3', '4', '5', '6', '7',
                          '8', '9', '10', '11', '12', '13', '14',
                          '15', '16', '17', '18', '19', '20', '21'],
'year_join': ['2015', '2016', '2017', '2015', '2016', '2017', '2015',
              '2015', '2016', '2017', '2015', '2016', '2017', '2015',
              '2015', '2016', '2017', '2015', '2016', '2017', '2015'],
'continent' : ['Europe', 'Asia', 'Europe', 'Africa', 'Asia', 'Europe', 'Africa',
               'Asia', 'Europe', 'Africa', 'Asia', 'Europe', 'Africa', 'Asia',
               'Africa', 'Africa', 'Asia', 'Europe', 'Africa', 'Asia', 'Europe']}) 
 

После того, как я повозился с этим кодом, я получаю график

 # 1. Group data data by year_join and continent into new dataframe (maybe to complicated, found code on Stack)
grouped = (pd.DataFrame(df.groupby(['continent', 'year_join']).size().reset_index(name="count")).pivot(columns='continent', index='year_join', values='count'))

# 2. Bring value counts into dictionary
result = {}
for columnName in grouped:
    result[columnName] = [*grouped[columnName]]
    
# 3. Create lists    
year = grouped.index.values.tolist()
y = list(dict.values(result))

# 4. Create stackplot from lists
plt.stackplot(year, y)
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
 

Однако, во-первых, легенда не отображается, и, в более общем плане, я сомневаюсь, что имеет смысл передавать данные из одного фрейма данных в другой в словарь в список перед его построением. У кого-нибудь есть советы о том, как это улучшить?

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

1. Можно ли выполнить этот код? Возникает синтаксическая ошибка с незакрытыми круглыми скобками, и генерируется пустой график. Я что-то упустил? Пожалуйста, проверьте свой воспроизводимый пример.

2. Действительно, отсутствовала скобка, и пропущенные значения привели к тому, что график был пустым. Обновлен код, теперь он должен быть работоспособным

Ответ №1:

Рассмотрите возможность использования API-интерфейса Pandas plot, DataFrame.plot , который объединяет объекты Pandas с объектами Matplotlib. Кроме того, groupby pivot по сути pivot_table , агрегирует данные при повороте. Следовательно, вы можете упростить свои потребности с помощью более простых шагов:

 pvt_df = df.pivot_table(index='year_join', columns='continent', aggfunc = 'count')
pvt_df.columns = pvt_df.columns.get_level_values(1)   # FLATTENS HIERARCHICAL COLUMNS
pvt_df
# continent  Africa  Asia  Europe
# year_join                      
# 2015          2.0   NaN     1.0
# 2016          NaN   2.0     NaN
# 2017          NaN   NaN     2.0

pvt_df.plot(kind='bar', stacked=True, rot=0, title='Year Joined and Continent Count')

plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
plt.clf()
plt.close()
 

Вывод графика

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

1. Отлично, спасибо! Оба хороших совета, чтобы упростить это. Код воспроизводится для меня. Просто для согласованности я бы изменил kind='bar' kind='area' , чтобы получить участок области, на который я ссылался в своем вопросе.