Search code examples
pythonpandasmatplotlibpivot-tablegrouped-bar-chart

Pivot Table and Bar Chart


Excel Pivot Output

Python Pivot Table

Python Pivot Chart

I would like to bring the same tabular and graphical output in Python. I tried changing the index, columns, and values but I only get errors such as the following:

  • No numeric types to aggregate
  • positional argument follows keyword argument
  • pivot_table() got multiple values for argument 'values'

I would like the output to be exactly like excel's output.

Sample DATA in text form:

  columns: Transport Type, October, November, December, January, February, March, April, May, June, July, August, September

'Bus','63,438','90,027','40,584','9,497','90,252','65,717','684','21,344', '56,517','28,114','49,966','44,406'
'Bus','112,429','163,675','83,016','16,438','160,933','122,607','1,690','47,059','116,104','56,444','95,275','83,223' 

'Train','50,398','73,483','37,711','7,222','70,329','52,495','723','22,469', '60,685','33,011','55,747','52,311'
'Train','115,340','171,494','83,725','21,138','177,074','127,344','1,266', '50,432','134,814','75,109','129,841','125,747'

Solution

  • You can use Seaborn's barplot with the data in long form:

    import pandas as pd
    import numpy as np
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    sns.set()
    columns= ['Transport Type', 'October', 'November', 'December', 'January', 'February', 'March', 'April',
              'May', 'June', 'July', 'August', 'September']
    data =[['Bus','63,438','90,027','40,584','9,497','90,252','65,717','684','21,344','56,517','28,114','49,966','44,406'],
           ['Bus', '112,429','163,675','83,016','16,438','160,933','122,607','1,690','47,059','116,104','56,444','95,275','83,223'],
           ['Train','50,398','73,483','37,711','7,222','70,329','52,495','723','22,469','60,685','33,011','55,747','52,311'],
           ['Train','115,340','171,494','83,725','21,138','177,074','127,344','1,266','50,432','134,814','75,109','129,841','125,747']]
    df = pd.DataFrame(data=data, columns=columns)
    for col in columns[1:]:
        df[col] = pd.to_numeric(df[col].str.replace(',', ''))
    
    table = pd.pivot_table(df, index='Transport Type', aggfunc=np.mean)
    
    table_long = pd.melt(table.reset_index(), id_vars='Transport Type', var_name='Month', value_name='Mean')
    ax = sns.barplot(data=table_long, x='Mean', y='Month',
                     orient='horizontal', hue='Transport Type', order=columns[1:])
    ax.set_title('Student Usage')
    ax.set_xlabel('Average Taps Ons & Offs')
    plt.tight_layout()
    plt.show()
    

    example plot

    PS: For a black background, you might experiment with:

    sns.set(style="ticks", context="talk")
    plt.style.use("dark_background")