【问题标题】:In matplotlib pyplot, how to group bars in a bar plot by category?在 matplotlib pyplot 中,如何按类别对条形图中的条形进行分组?
【发布时间】:2020-06-26 09:16:16
【问题描述】:

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

我有两个数组,例如

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

【问题讨论】:

  • 那么,user_score 是 y 轴,user_type 是颜色,你的 x 轴是什么?
  • 能否将相关的源数据添加到问题中?
  • @Anwarvic x 轴无关紧要——条形只需要按颜色或按 x 轴上的间距进行分类。
  • @Roy2012 添加了我正在使用的实际数据。我正在为认知无线电网络中的用户模拟信任值。
  • @arcanaxion,我添加了一个适用于您的数据的答案

标签: python matplotlib plot categorical-data


【解决方案1】:

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

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 轴发挥了作用

【讨论】:

  • 谢谢!这对我来说很完美。
  • 很高兴我能帮上忙 :)
【解决方案2】:

您可以像这样遍历'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()

得到这个情节:


最后,如果你想提高一点bar的可视化,你可以使用一个透明度值:

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

给出:

【讨论】:

  • 感谢您的回答。如果我想要 this? 那样的结果怎么办?我正在使用我编辑过的帖子中的源数据。
  • @JohanC 肯定 dodge 参数有助于改善可视化,感谢您的建议,我更新了我的答案
  • 抱歉,我认为我发布的最初示例条形图具有误导性。我只有 2 个数组,user_utilisation_ratinguser_type。我想按颜色对具有相同user_type 的条形图进行分组,并在图例中指明。
猜你喜欢
  • 2018-11-29
  • 2012-05-08
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 2019-03-10
  • 2014-05-03
相关资源
最近更新 更多