Search code examples
pythonmatplotlibplotcategorical-data

In matplotlib pyplot, how to group bars in a bar plot by category?


First off, I'm not trying to make a regular grouped bar plot.

I have two arrays such as

user_score = [70, 95, 86, 50, 17]
user_type = ['High', 'High', 'High', 'Mid', 'Low']

I'm trying to create a bar plot such that bars of a same category (user_type in this case) are grouped together by separation or color.

Example image of what I'm trying to achieve

Fig. 1

How do I do this in pyplot?

Currently for my actual use case I'm only able to achieve this:

Fig. 2

Edit:

1.

Actual data:

user_utilisation_rating = [0.0, 0.0, 0.0, 0.06, 0.09, 0.12, 0.13, 0.13, 0.14, 0.14, 0.16, 0.26, 0.3, 0.53, 0.54, 0.56, 0.76, 0.79, 1.0, 1.0]
user_type = ['Minimum', 'Minimum', 'Minimum', 'Consistent low', 'Consistent low', 'Consistent low', 'Consistent low', 'Consistent low', 'Consistent low', 'Consistent low', 'Consistent low', 'Ending low', 'Ending low', 'Start low', 'Start low', 'Start low', 'Consistent high', 'Consistent high', 'Maximum', 'Maximum']

2.

Changed Fig 1 to style more similar to what I'm trying to do with regards to my actual plot in Fig 2.

3.

Trying to accomplish it with this but only 1 bar appears per user_type. Not sure what I'm doing wrong.

import pandas as pd

user_pd = pd.DataFrame({
    'utilisation' : users_utilisation_rating,
    'type' : user_type
})

user_pd.sort_values(by=['utilisation'], inplace=True)

fig, ax = plt.subplots(figsize = (14, 10))

for tp in user_pd['type'].unique():
    ax.bar(user_pd[user_pd['type'] == tp]['type'],
           user_pd[user_pd['type'] == tp]['utilisation'],
           label = tp)

ax.legend()
plt.show()

Solution

  • According to your data, you can do something like this:

    color_map = {"Start low": "#581845",
                "Consistent low": "#900C3F",
                "Ending low":"#C70039",
                "Minimum":"#FF5733",
                "Consistent high":"#FFC300",
                "Maximum":"#509916"}
    
    
    df = pd.DataFrame({"user_rating": user_utilisation_rating,
                      "user_type": user_type})
    df.plot.bar(x='user_type', y='user_rating', rot=45,
              color=[color_map[i] for i in user_type])
    plt.legend().remove()
    plt.show()
    

    Which produces something like this: enter image description here

    NOTE: Notice that I've removed the legend as the x-axis does its role