c200402
c200402

Reputation: 165

Pandas Grouped Bar Chart Displayed in Descending Order

I have a grouped bar chart of 2 columns Gender and Churn Category. I want to sort the chart in descending order so that it displays as Competitor, Dissatisfaction, Attitude, etc.

I tried to put an ascending command at the end, but received an error message.

My code:

pd.crosstab(df['Churn Category'], df['Gender']).plot(kind="bar", figsize=(15, 5))

plt.title("Frequency of Churn Category by Gender")
plt.xlabel("Churn Category")
plt.ylabel("Count")
plt.show()

enter image description here

Upvotes: 2

Views: 209

Answers (1)

Cold Fish
Cold Fish

Reputation: 332

One approach is to take the value_counts() of the Churn Category column and use that to construct an ordered categorical data type. Taking the value_counts() of a column will return a series ordered descendingly. The index of this series can be used to create the ordered categorical data type.

Once that is done you can set the data type of the Churn Category column in the original dataframe to be the ordered categorical type you just created.

Pandas will now respect that order when you crosstab.

Here's a minimum reproducible example of that approach:

import pandas as pd
from matplotlib import pyplot as plt
from pandas.api.types import CategoricalDtype

df = pd.DataFrame(
    {
        'Churn Category':
            ['Competitor', 'Dissatisfaction', 'Attitude', 'Other', 'Price', 'Dissatisfaction', 'Attitude', 'Price',
             'Other', 'Competitor', 'Dissatisfaction', 'Competitor', 'Competitor', 'Attitude', 'Attitude', 'Attitude',
             'Attitude', 'Attitude', 'Attitude'],
        'Gender':
            ['Male', 'Male', 'Male', 'Female', 'Male', 'Male', 'Female', 'Male', 'Female', 'Male', 'Male', 'Female',
             'Male', 'Male', 'Female', 'Male', 'Female', 'Male', 'Male']
    }
)

# value_counts defaultly returns a descending order.
churn_category_counts = df['Churn Category'].value_counts().index
ordered_categorical_churn_type = CategoricalDtype(categories=churn_category_counts)
df['Churn Category'] = df['Churn Category'].astype(ordered_categorical_churn_type)
pd.crosstab(df['Churn Category'], df['Gender']).plot(kind="bar", figsize=(15, 5))

plt.title("Frequency of Churn Category by Gender")
plt.xlabel("Churn Category")
plt.ylabel("Count")
plt.show()

Upvotes: 1

Related Questions