JJJJeEEEE
JJJJeEEEE

Reputation: 27

sort x-axis in a certain order for grouped bar plot in Python

I want my axis to be in the order ['Good or Better','Fair', 'Poor', 'Very Poor'] Is there any way to do that without changing my current code too much?

data.groupby('PAVEMENT CONDITIONS')['FISCAL YEAR'].value_counts().unstack().plot.bar()
plt.title("Total data section of different years for each pavement condition")
plt.xlabel('Pavement Condition')
plt.ylabel('Number of sections')
plt.xticks(rotation=0)
plt.show()

Current Plot

Upvotes: 2

Views: 2104

Answers (1)

Henry Ecker
Henry Ecker

Reputation: 35626

Easiest way is with reindex:

ax = (
    data.groupby('PAVEMENT CONDITIONS')['FISCAL YEAR']
        .value_counts()
        .unstack()
        .reindex(['Good or Better', 'Fair', 'Poor', 'Very Poor'])  # Specify order here
        .plot.bar()
)

Or create a CategoricalDType and order as Categorical Data:

# Establish Categories and order
cat_type = pd.CategoricalDtype(
    categories=['Good or Better', 'Fair', 'Poor', 'Very Poor'],
    ordered=True
)

# Change Type of PAVEMENT CONDITIONS to specified Categorical Type
data['PAVEMENT CONDITIONS'] = data['PAVEMENT CONDITIONS'].astype(cat_type)
ax = (
    data.groupby('PAVEMENT CONDITIONS')['FISCAL YEAR']
        .value_counts()
        .unstack()  # Uses categorical ordering
        .plot.bar()
)

Both Produce:

plt.title("Total data section of different years for each pavement condition")
plt.xlabel('Pavement Condition')
plt.ylabel('Number of sections')
plt.xticks(rotation=0)
plt.legend(title='FISCAL YEAR', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()

plot


Sample Data Used:

np.random.seed(5)
data = pd.DataFrame({
    'FISCAL YEAR': np.random.randint(2014, 2021, 1000),
    'PAVEMENT CONDITIONS': np.random.choice(
        ['Good or Better', 'Fair', 'Poor', 'Very Poor'], 1000)
})

data.head(10):

   FISCAL YEAR PAVEMENT CONDITIONS
0         2017           Very Poor
1         2020                Fair
2         2019                Fair
3         2020      Good or Better
4         2020                Poor
5         2014                Fair
6         2015                Poor
7         2014                Poor
8         2018                Poor
9         2020                Fair

Upvotes: 3

Related Questions