Comment créer un graphique à barres empilées avec une série chronologique et des valeurs agrégées
Nov 25 2020
J'ai des difficultés à créer une série chronologique de graphique à barres empilées à partir de ma trame de données Pandas (image ci-dessous). Je voudrais avoir la «Date» sur l'axe des x, les «Heures» sur l'axe des y et chaque barre pour afficher le temps passé avec chaque groupe dans «Catégorie».

Dois-je utiliser Pandas - Fonction Groupby? Le dataframe est un exemple. J'ai des centaines de lignes de données de 2018 à 2020.
Réponses
3 TrentonMcKinney Nov 25 2020 at 07:35
- Il existe une solution aux pandas: un graphique à barres empilées avec des données chronologiques
- Le problème avec cette question, c'est que OP n'agrège aucune donnée, donc cette solution ne fonctionne pas pour cette question.
- Utiliser
pandas.DataFrame.groupby
sur'date'
et'group'
, lors de l'agrégation.sum
sur'time'
- L'
.dt
extracteur est utilisé pour extraire uniquement le.date
composant de la'date'
colonne. - Assurez-vous que la
'Date'
colonne de votre dataframe est correctement formatée en tant quedatetime
dtype
, avecdf.Date = pd.to_datetime(df.Date)
- L'
- Le dataframe groupé,,
dfg
doit être mis en forme dans la forme correcte, ce qui peut être accompli avecpandas.DataFrame.pivot
. - Le moyen le plus simple d'empiler un graphique à barres consiste à
pandas.DataFrame.plot.bar
utiliser lestacked
paramètre.- Voir
pandas.DataFrame.plot
pour tous les paramètres.
- Voir
import pandas as pd
import matplotlib.pyplot as plt
import random # for test data
import numpy as np # for test data
# setup dataframe with test data
np.random.seed(365)
random.seed(365)
rows = 1100
data = {'hours': np.random.randint(10, size=(rows)),
'group': [random.choice(['A', 'B', 'C']) for _ in range(rows)],
'date': pd.bdate_range('2020-11-24', freq='h', periods=rows).tolist()}
df = pd.DataFrame(data)
# display(df.head())
hours group date
0 2 C 2020-11-24 00:00:00
1 4 B 2020-11-24 01:00:00
2 1 C 2020-11-24 02:00:00
3 5 A 2020-11-24 03:00:00
4 2 B 2020-11-24 04:00:00
# use groupby on df
dfg = df.groupby([df.date.dt.date, 'group'])['hours'].sum().reset_index()
# pivot the dataframe into the correct format
dfp = dfg.pivot(index='date', columns='group', values='hours')
# display(dfp.head())
group A B C
date
2020-11-24 49 25 29
2020-11-25 62 18 57
2020-11-26 42 77 4
2020-11-27 34 43 17
2020-11-28 28 53 23
# plot the pivoted dataframe
dfp.plot.bar(stacked=True, figsize=(10, 6), ylabel='Hours', xlabel='Date', title='Sum of Daily Category Hours')
plt.legend(title='Category', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show()

- Il y aura une barre pour chaque jour, c'est ainsi que fonctionnent les graduations des graphiques à barres, de sorte que le graphique peut être très large, s'il y a plusieurs dates.
- Pensez à utiliser
pandas.DataFrame.barh
dfp.plot.barh(stacked=True, figsize=(6, 10), title='Sum of Daily Category Hours')
plt.legend(title='Category', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.xlabel('Hours')
plt.ylabel('Date')
plt.show()

- L'OP indique qu'il existe des données de 2018 à 2020, ce qui signifie qu'il pourrait y avoir plus de 700 jours de données, ce qui se traduit par plus de 700 barres dans le graphique à barres.
- Un tracé linéaire standard peut être la meilleure option pour visualiser correctement les données.
dfp.plot(figsize=(10, 6))
plt.show()
