在 matplotlib pyplot 中,如何按类别对条形图中的条形进行分组?

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

首先,我并不是要制作常规的分组条形图。

我有两个数组,例如

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

我正在尝试创建一个条形图,以便将同一类别的条形图(在本例中为 user_type)按分隔或颜色组合在一起。

我正在努力实现的示例图片

图1

如何在 pyplot 中执行此操作?

目前对于我的实际用例我只能做到这一点:

图2

编辑:

1.

实际数据:

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.

将图 1 更改为与我在图 2 中的实际情节相关的样式更相似。

3.

试图用这个来完成它,但每个 user_type 只出现 1 个柱状图。不确定我做错了什么。

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()

您可以像这样遍历 'cylinders' 列中的唯一元素:

import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv('mpg.csv')
df.sort_values(by = ['cylinders', 'mpg'], inplace = True)

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

for cyl in df['cylinders'].unique():
    ax.bar(df[df['cylinders'] == cyl]['name'],
           df[df['cylinders'] == cyl]['mpg'],
           label = cyl)
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)
ax.legend()

plt.show()

并得到这个情节:


或者您可以使用 seaborn.barplot:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

df = pd.read_csv('mpg.csv')
df.sort_values(by = ['cylinders', 'mpg'], inplace = True)

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

sns.barplot(x = df['name'],
            y = df['mpg'],
            hue = df['cylinders'],
            dodge = False)
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)

plt.show()

并得到这个情节:


最后,如果你想稍微提高条形的可视化,可以使用透明度值:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

df = pd.read_csv('mpg.csv')
df.sort_values(by = ['cylinders', 'mpg'], inplace = True)

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

sns.barplot(x = df['name'],
            y = df['mpg'],
            hue = df['cylinders'],
            edgecolor = 'k',
            dodge = False,
            alpha = 0.3)
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)

plt.show()

给出:

根据你的数据,你可以这样做:

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()

产生如下内容:

注意:请注意,我已经删除了图例,因为 x 轴发挥了作用