2

I am new to pandas and matplotlib and trying to accomplish following. I have a data frame as shown below which is actually a listing the performance of players based on match date

name          runs  match_date  player_id
Dockrell, G H   0   2018-06-17  3752
Stirling, P R   81  2018-06-17  3586
O'Brien, K J    28  2018-06-17  3391
McCarthy, B J   0   2018-06-17  4563
Poynter, S W    0   2018-06-17  4326
Poynter, S W    2   2018-06-17  4326
McCarthy, B J   0   2018-06-17  4563
Shannon, J N K  5   2018-06-17  4219
Shannon, J N K  6   2018-06-17  4219
Stirling, P R   51  2018-06-17  3586

This is a subset of data that I have created based on following code

match_performance = dataFrame[['name','runs','match_date','player_id']].sort_values('match_date',ascending=False).groupby('player_id').head(5)
sns.set_context({"figure.figsize": (10, 4)})
ax = sns.barplot(x="name", y="runs",  data=match_performance)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90) 

Resultant graph

I need to plot this either as stacked bar or grouped bar to display performance of players in there last 5 matches based on player id which I have in the dataframe but I am not sure how to go about plotting this data as required.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Neel
  • 613
  • 4
  • 14
  • 32

2 Answers2

0

Michael Waskom, the creater of Seaborn posted this on Twitter:

@randyzwitch I don't really like stacked bar charts, I'd suggest maybe using pointplot / factorplot with kind=point

— Michael Waskom (@michaelwaskom) September 4, 2014

Regretfully, the answer is no. There is no built-in function in Seaborn for plotting stacked bar charts.

filiphl
  • 921
  • 1
  • 8
  • 15
  • I know that stacked bars are not possible in seaborn that is why I am open to grouped bars for which I have seen several examples but I am not able to get them working in my case – Neel Jul 10 '18 at 13:13
  • I am sorry. I did not get that impression from your question. You could go for a grouped bar chart, though in this case it would be messy. Anyway, feel free to try out the hue argument to seaborn barplot. – filiphl Jul 10 '18 at 13:24
0

While this is an older question I found it while looking for a solution, so I hope this may help someone. Achieving stacked bars are a bit tricky with seaborn, but this should do the trick

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

def stacked_chart_sns(df, x, y, group_by, palette):
    array_of_dfs = []
    w_0 = None
    for u in df[group_by].unique():
        w = df[df[group_by] == u].copy()
        if w_0 is not None:
            w = w.merge(w_0, how='outer').fillna(0)
            w[group_by] = u
            w[y] = w.apply(lambda x: x[y] + x['y_prev'], axis=1)
            w = w.drop(columns=['y_prev'])
        array_of_dfs += [w]
        w_0 = w.drop(columns=[group_by]).rename(columns={y:'y_prev'}).copy()

    patches = []
    for i, d in enumerate(array_of_dfs[::-1]):
        sns.barplot(x=x, y=y, data=d, color=palette[i])
        patches += [mpatches.Patch(label=list(df[group_by].unique())[::-1][i], color=palette[i])]

    plt.legend(handles=patches, loc = 'upper left', ncol=1, labelspacing=1)
    plt.show()

### use it with - for the example data in the question:
stacked_chart_sns(match_performance, 'match_date', 'runs', 'player_id', sns.color_palette("Spectral"))

bencekd
  • 1,575
  • 1
  • 12
  • 8
  • Thanks for the code. I just tried this but there seems to be some problem as I get index out of range error at the line sns.barplot. It seems related to color palette part of the code. I tried but couldn't fix it as there is no explanation of the code itself. Is it possible for you to help?? – Neel Jul 29 '19 at 07:16
  • By default `sns.color_palette("Spectral")` gives back a color palette of 5 colours. If you want to get more than that (and therefore avoid the out of range error) you can set it to generate more palette elements with `sns.color_palette("Spectral",10)` where 10 is the number of colors to generate. You can also tune the code a bit and rewrite the function to 'detect' how many palette elements will it need. – bencekd Jul 30 '19 at 14:07