且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在同一图中分组和绘制组

更新时间:2023-02-14 13:00:07

  • groupbystack 数据帧要容易得多.
    • minmax 可以同时聚合.
  • seabornmatplotlib 的高级 API,所以我推荐使用

    I have that code for plotting a chart:

    destinations = ['JPA', 'FOR']
    
    for destiny in destinations:
    
        df_tmp = df[(df.DESTINY == destiny)]
        df_tmp['max'] = df_tmp.groupby('DAYS_UNTIL_DEPARTURE')['COST'].transform('max')
        df_tmp['min'] = df_tmp.groupby('DAYS_UNTIL_DEPARTURE')['COST'].transform('min')
    
        plt.figure(figsize=(10,2))
        sns.lineplot(x="DAYS_UNTIL_DEPARTURE", y="min", data=df_tmp, ci=None, palette="muted", label='min')
        sns.lineplot(x="DAYS_UNTIL_DEPARTURE", y="max", data=df_tmp, ci=None, palette="muted", label='max')
        plt.title(destiny , fontweight="bold", fontsize=16, pad=20)
        plt.ylabel('Cost')
        plt.show()
        
    

    The code works pretty well.

    I would like to know how to plot the multiple charts on the same figure? In other words, two charts in one figure.

    I’ve been trying to subplot, but I wasn’t enabled to get the result expected.

    Thanks, thanks.

    Here is a sample of my data:

    DAYS_UNTIL_DEPARTURE,DESTINY,COST
    10,JPA,100
    9,JPA,90
    8,JPA,85
    7,JPA,86
    6,JPA,87
    5,JPA,71
    4,JPA,90
    3,JPA,77
    2,JPA,88
    1,JPA,87
    0,JPA,74
    10,FOR,99
    9,FOR,90
    8,FOR,96
    7,FOR,79
    6,FOR,84
    5,FOR,74
    4,FOR,85
    3,FOR,74
    2,FOR,88
    1,FOR,100
    0,FOR,87
    

    • It's much easier to groupby, and stack the dataframe.
      • Both min, and max can be aggregated at the same time.
    • seaborn is a high-level API for matplotlib, so I recommend using seaborn.relplot, to plot both destinations in the same figure
    import pandas as pd
    import numpy as np  # for sample data
    import random  # for sample data
    import seaborn as sns
    import matplotlib.pyplot as ply
    
    # create sample data
    np.random.seed(365)
    random.seed(365)
    rows = 300
    data = {'days': np.random.randint(10, size=(rows)), 'dest': [random.choice(['JPA', 'FOR']) for _ in range(rows)], 'cost': np.random.randint(70, 120, size=(rows))}
    df = pd.DataFrame(data)
    
    # groupby, aggregate, and stack
    dfg = df.groupby(['dest', 'days'])['cost'].agg(['min', 'max']).stack().reset_index().rename(columns={'level_2': 'range', 0: 'vals'})
    
    # plot with seaborn relplot
    (sns.relplot(x='days', y='vals', hue='range', col='dest', data=dfg, kind='line')
     .set_axis_labels('Day Until Departure', 'Cost')
     .set_titles('Destination: {col_name}'))