Search code examples
pythoncolorsseabornbar-chart

Change barpolot color in based on a range of x values


I am trying to make a seaborn barplot that plots values (baseball team ERA's) from different years - and then highlight the bars based on the year ranges under different management.

import pandas as pd
import pybaseball as pyb
import seaborn as sns
from matplotlib import pyplot
import numpy as np

cards_pitching_df = pyb.team_pitching(start_season=1996,end_season=2020)
cards_pitching_df = cards_pitching_df.loc[(cards_pitching_df['Team'] == "STL"), :"Pitches"]
cards_pitching_df = cards_pitching_df.sort_values(by='Season', ascending=False)

era = list(cards_pitching_df['ERA'])
season = list(cards_pitching_df['Season'])

df_season_era = list(zip(era,season))
df_season_era = pd.DataFrame(df_season_era, columns=['ERA','Season'])
df_season_era
        ERA    Season
    0   3.92    2020
    1   3.82    2019
    2   3.85    2018
    3   4.01    2017
    4   4.08    2016
    5   2.94    2015
    6   3.50    2014
    7   3.43    2013
    8   3.71    2012
    9   3.79    2011

And as of now, I have my seaborn barplot highlighting based on the ERA values, see below. But what I want is one color (say blue) for the ERA's between the years 1996-2011, green for 2012-2017, and orange for 2018-2020, which are the x - values.

era_chart_2 = sns.barplot(x=season, y=era, data=df_season_era)
for bar in era_chart2.patches:
    if bar.get_height() > 3.5:
        bar.set_color('grey')    
    else:
        bar.set_color('green')

See the chart it is now producing here

Any suggestions on how to make the bars colored in this way? Thanks!


Solution

  • You can use palette to add the range of preferred colors in seaborn.

    Use this:

    palette=['blue' if val in range(1996,2012) else 'green' if val in range(2012,2018) else 'orange' for val in sorted(df_season_era['Season'].tolist())]
    
    sns.barplot('Season', 'ERA', data=df_season_era, palette=palette)
    

    Notice: In range() function the upper limit is always upper_limit - 1. So that is why I have used range(1996,2012) and range(2012,2018) instead of range(1996,2011) and range(2012,2017)