pythondataframeplotstacked

Stacked bar plot in a for loop


i'm trying to make a stacked plot bar. Problem is I have to do it in for loop, and I don't know how to manage the "bottom" parameter in the loop.

fig, ax = plt.subplots(1, figsize=(20,5), dpi=200, sharex=True)
fig.suptitle('titre',fontsize=14)
n = 7
color = iter(cm.rainbow(np.linspace(0, 1, n)))
car_list = ['dangel','tepee', 'ranger', 'duster', 'metro']
for i in car_list :
    c = next(color)
    ax.bar(globals()[f"df_{i}"]['date debut'], globals()[f"df_{i}"]['durée'], color=c, label=i, width=10.0, bottom=???)

Don't know if it's matter but the dataframes uses the same timeline off course, but some times for a specific date, there is no value, so bottom could be zero (or nothing at all if there is no row in this date ?).

EDIT : here some sample of the dataframes (with a lot less data in time in order not to flood the topic). Note : duster is really more recent, so dates are not match with others dataframes.

df_dangel :

    vehicule    date debut  date fin    durée
349 Dangel 4x4 prio. terrain    2019-01-10 09:00:00 2019-01-10 16:00:00 7.0
350 Dangel 4x4 prio. terrain    2019-01-14 14:00:00 2019-01-14 15:30:00 1.5
351 Dangel 4x4 prio. terrain    2019-01-15 09:00:00 2019-01-15 12:00:00 3.0
352 Dangel 4x4 prio. terrain    2019-01-15 13:30:00 2019-01-15 17:00:00 3.5
353 Dangel 4x4 prio. terrain    2019-01-16 08:00:00 2019-01-16 20:00:00 12.0
354 Dangel 4x4 prio. terrain    2019-01-17 08:00:00 2019-01-17 17:00:00 9.0
355 Dangel 4x4 prio. terrain    2019-01-18 08:00:00 2019-01-18 20:00:00 12.0
356 Dangel 4x4 prio. terrain    2019-01-22 08:00:00 2019-01-22 20:00:00 12.0

df_tepee :

    vehicule    date debut  date fin    durée
1668    Tepee   2019-01-17 11:00:00 2019-01-17 16:00:00 5.0
1669    Tepee   2019-01-17 16:00:00 2019-01-18 20:00:00 28.0
1670    Tepee   2019-01-22 11:00:00 2019-01-22 18:00:00 7.0
1671    Tepee   2019-01-23 08:00:00 2019-01-23 15:00:00 7.0
1672    Tepee   2019-01-24 08:00:00 2019-01-25 20:00:00 36.0
1673    Tepee   2019-01-29 08:00:00 2019-01-29 18:30:00 10.5
1674    Tepee   2019-01-31 08:30:00 2019-01-31 09:30:00 1.0
1675    Tepee   2019-01-31 09:30:00 2019-01-31 11:00:00 1.5

df_ranger :

    vehicule    date debut  date fin    durée
1037    Ranger 4x4 prio. terrain    2019-01-08 10:00:00 2019-01-08 12:00:00 2.0
1038    Ranger 4x4 prio. terrain    2019-01-11 15:00:00 2019-01-11 18:00:00 3.0
1039    Ranger 4x4 prio. terrain    2019-01-14 08:00:00 2019-01-14 20:00:00 12.0
1040    Ranger 4x4 prio. terrain    2019-01-16 08:00:00 2019-01-16 13:00:00 5.0
1041    Ranger 4x4 prio. terrain    2019-01-22 08:00:00 2019-01-22 16:00:00 8.0
1042    Ranger 4x4 prio. terrain    2019-01-23 08:00:00 2019-01-23 15:00:00 7.0
1043    Ranger 4x4 prio. terrain    2019-01-24 08:00:00 2019-01-24 17:30:00 9.5
1044    Ranger 4x4 prio. terrain    2019-01-29 08:00:00 2019-01-29 20:00:00 12.0

df_duster :

    vehicule    date debut  date fin    durée
1349    Duster 4x4 prio. terrain    2021-07-08 08:00:00 2021-07-12 09:00:00 97.0
1350    Duster 4x4 prio. terrain    2021-07-15 08:00:00 2021-07-16 20:00:00 36.0
1351    Duster 4x4 prio. terrain    2021-07-28 08:00:00 2021-07-28 20:00:00 12.0
1352    Duster 4x4 prio. terrain    2021-08-30 08:00:00 2021-09-03 20:00:00 108.0
1353    Duster 4x4 prio. terrain    2021-09-06 08:00:00 2021-09-06 20:00:00 12.0
1354    Duster 4x4 prio. terrain    2021-09-14 17:00:00 2021-09-16 20:00:00 51.0
1355    Duster 4x4 prio. terrain    2021-09-20 08:00:00 2021-09-20 20:00:00 12.0
1356    Duster 4x4 prio. terrain    2021-09-23 08:00:00 2021-09-23 19:00:00 11.0

df_metro :

    vehicule    date debut  date fin    durée
2265    Métrovélo   2019-01-11 09:30:00 2019-01-11 13:30:00 4.0
2266    Métrovélo   2019-01-18 10:00:00 2019-01-18 14:00:00 4.0
2267    Métrovélo   2019-01-22 12:30:00 2019-01-22 14:00:00 1.5
2268    Métrovélo   2019-01-25 16:00:00 2019-01-25 19:00:00 3.0
2269    Métrovélo   2019-02-08 16:30:00 2019-02-08 19:30:00 3.0
2270    Métrovélo   2019-02-15 16:30:00 2019-02-15 19:00:00 2.5
2271    Métrovélo   2019-03-07 12:00:00 2019-03-07 14:00:00 2.0
2272    Métrovélo   2019-03-08 16:30:00 2019-03-08 18:30:00 2.0

First column is the the remained indice from the "all data file" which I'm cutting to clarify dataframes.

And without the bottom parameter, this is what I have :

enter image description here


Solution

  • Consider a horizontal concatenation of multiple data frames, then plot with pandas.plot rather than the matplotlib implementation. With this approach, no for loop or bottom argument is needed:

    Plot

    # BUILD DICTIONARY OF TIME SERIES
    car_list = ['dangel', 'tepee', 'ranger', 'duster', 'metro']
    car_df_list = [df_dangel, df_tepee, df_ranger, df_duster, df_metro]
    
    car_ts_dict = {
       car: df.set_index('date debut')['durée']
       for car, df in 
       zip(car_list, car_df_list)
    }
    
    # HORIZONTAL MERGE BY DATETIME
    car_df = pd.concat(car_ts_dict, axis=1).fillna(0)
    
    fig, ax = plt.subplots(figsize=(20,5), dpi=200)
    fig.suptitle('titre', fontsize=14)
    
    car_df.plot(
        kind='bar', stacked=True, colormap="rainbow", ax=ax
    )
    
    plt.xticks(rotation=45, ha='right')
    plt.tight_layout()
    plt.show()
    plt.clf()
    plt.close()
    

    Data

    from io import StringIO
    import pandas as pd
    
    def build_data_from_text(txt):
        with StringIO(txt) as t:
            df = pd.read_csv(
                t, parse_dates=["date debut", "date fin"], sep="\s+"
            )
        
        return df
    
    df_dangel_txt = '''    vehicule    "date debut"  "date fin"    durée
    349 "Dangel 4x4 prio. terrain"    "2019-01-10 09:00:00" "2019-01-10 16:00:00" 7.0
    350 "Dangel 4x4 prio. terrain"    "2019-01-14 14:00:00" "2019-01-14 15:30:00" 1.5
    351 "Dangel 4x4 prio. terrain"    "2019-01-15 09:00:00" "2019-01-15 12:00:00" 3.0
    352 "Dangel 4x4 prio. terrain"    "2019-01-15 13:30:00" "2019-01-15 17:00:00" 3.5
    353 "Dangel 4x4 prio. terrain"    "2019-01-16 08:00:00" "2019-01-16 20:00:00" 12.0
    354 "Dangel 4x4 prio. terrain"    "2019-01-17 08:00:00" "2019-01-17 17:00:00" 9.0
    355 "Dangel 4x4 prio. terrain"    "2019-01-18 08:00:00" "2019-01-18 20:00:00" 12.0
    356 "Dangel 4x4 prio. terrain"    "2019-01-22 08:00:00" "2019-01-22 20:00:00" 12.0'''
    
    
    df_tepee_txt = '''    vehicule    "date debut"  "date fin"    durée
    1668    "Tepee"   "2019-01-17 11:00:00" "2019-01-17 16:00:00" 5.0
    1669    "Tepee"   "2019-01-17 16:00:00" "2019-01-18 20:00:00" 28.0
    1670    "Tepee"   "2019-01-22 11:00:00" "2019-01-22 18:00:00" 7.0
    1671    "Tepee"   "2019-01-23 08:00:00" "2019-01-23 15:00:00" 7.0
    1672    "Tepee"   "2019-01-24 08:00:00" "2019-01-25 20:00:00" 36.0
    1673    "Tepee"   "2019-01-29 08:00:00" "2019-01-29 18:30:00" 10.5
    1674    "Tepee"   "2019-01-31 08:30:00" "2019-01-31 09:30:00" 1.0
    1675    "Tepee"   "2019-01-31 09:30:00" "2019-01-31 11:00:00" 1.5'''
    
    
    df_ranger_txt = '''    vehicule    "date debut"  "date fin"    durée
    1037    "Ranger 4x4 prio. terrain"    "2019-01-08 10:00:00" "2019-01-08 12:00:00" 2.0
    1038    "Ranger 4x4 prio. terrain"    "2019-01-11 15:00:00" "2019-01-11 18:00:00" 3.0
    1039    "Ranger 4x4 prio. terrain"    "2019-01-14 08:00:00" "2019-01-14 20:00:00" 12.0
    1040    "Ranger 4x4 prio. terrain"    "2019-01-16 08:00:00" "2019-01-16 13:00:00" 5.0
    1041    "Ranger 4x4 prio. terrain"    "2019-01-22 08:00:00" "2019-01-22 16:00:00" 8.0
    1042    "Ranger 4x4 prio. terrain"    "2019-01-23 08:00:00" "2019-01-23 15:00:00" 7.0
    1043    "Ranger 4x4 prio. terrain"    "2019-01-24 08:00:00" "2019-01-24 17:30:00" 9.5
    1044    "Ranger 4x4 prio. terrain"    "2019-01-29 08:00:00" "2019-01-29 20:00:00" 12.0'''
    
    
    df_duster_txt = '''    vehicule    "date debut"  "date fin"    durée
    1349    "Duster 4x4 prio. terrain"   "2021-07-08 08:00:00" "2021-07-12 09:00:00" 97.0
    1350    "Duster 4x4 prio. terrain"   "2021-07-15 08:00:00" "2021-07-16 20:00:00" 36.0
    1351    "Duster 4x4 prio. terrain"   "2021-07-28 08:00:00" "2021-07-28 20:00:00" 12.0
    1352    "Duster 4x4 prio. terrain"   "2021-08-30 08:00:00" "2021-09-03 20:00:00" 108.0
    1353    "Duster 4x4 prio. terrain"   "2021-09-06 08:00:00" "2021-09-06 20:00:00" 12.0
    1354    "Duster 4x4 prio. terrain"   "2021-09-14 17:00:00" "2021-09-16 20:00:00" 51.0
    1355    "Duster 4x4 prio. terrain"   "2021-09-20 08:00:00" "2021-09-20 20:00:00" 12.0
    1356    "Duster 4x4 prio. terrain"   "2021-09-23 08:00:00" "2021-09-23 19:00:00" 11.0'''
    
    
    df_metro_txt = '''    vehicule    "date debut"  "date fin"    durée
    2265    "Métrovélo"   "2019-01-11 09:30:00" "2019-01-11 13:30:00" 4.0
    2266    "Métrovélo"   "2019-01-18 10:00:00" "2019-01-18 14:00:00" 4.0
    2267    "Métrovélo"   "2019-01-22 12:30:00" "2019-01-22 14:00:00" 1.5
    2268    "Métrovélo"   "2019-01-25 16:00:00" "2019-01-25 19:00:00" 3.0
    2269    "Métrovélo"   "2019-02-08 16:30:00" "2019-02-08 19:30:00" 3.0
    2270    "Métrovélo"   "2019-02-15 16:30:00" "2019-02-15 19:00:00" 2.5
    2271    "Métrovélo"   "2019-03-07 12:00:00" "2019-03-07 14:00:00" 2.0
    2272    "Métrovélo"   "2019-03-08 16:30:00" "2019-03-08 18:30:00" 2.0'''
    
    
    df_dangel = build_data_from_text(df_dangel_txt)
    df_tepee = build_data_from_text(df_tepee_txt)
    df_ranger = build_data_from_text(df_ranger_txt)
    df_duster = build_data_from_text(df_duster_txt)
    df_metro = build_data_from_text(df_metro_txt)
    

    Output

    Plot Output