【问题标题】:plotting data frame grouped by multiple columns绘制按多列分组的数据框
【发布时间】:2022-08-16 14:44:23
【问题描述】:

我有一个名为 crs 的数据框,如下所示:

| Brand | Mark | Milage |
|:---- |:------:| -----:|
| A  | w   | 100k |
| A  | w   | 220k |
| A  | v  | 250k |
| A  | v   | 100k |
| B  | s   | 120k |
| B  | t   | 190k |
| B  | t   | 200k |
| C  | u  | 160k |
| C  | u   | 170k |

为了绘制每个品牌的最小里程数,我做了

min_dist_each_brand=crs.groupby(\'brand\', as_index=False).agg({\'milage\': \'min\'})

然后

min_dist_each_brand.plot(x=\'brand\', kind=\'bar\')

如果我想为每个 \'Mark\' 绘制相同的内容,我会重复相同的代码,同时将 \'brand\' 替换为 \'Mark\'。但我希望能够在不制作新数据框的情况下为每个品牌或标记绘制 min_dist。 我知道我可以按如下方式对多列进行分组;

min_dist=crs.groupby(by=[\'brand\', \'mark\']).agg({\'milage\': \'min\'})

无论如何我可以绘制每个品牌的最小里程并使用这个新的 min_dist 数据框进行标记?

谢谢你。

    标签: python plot


    【解决方案1】:

    要将品牌和标记都显示为图形,您将需要两个级别的 x 轴标签。第一个(标记)可以从级别 1 索引中获取并设置为 xticklables。第二级有点手动。由于有 5 个最小值,其中 A、B 和 C 各有两个,因此我将第二个标签的位置拆分为 0.2、0.6 和 0.9,以便它们位于刻度之间(对于 A 和 B),而对在 C 的刻度下。-0.1 将调整第二个标签的高度。

    min_dist=crs.groupby(by=['brand', 'mark']).agg({'milage': 'min'})
    fig, ax = plt.subplots(figsize=(10,6))
    min_dist.plot(kind='bar', xlabel='', ax=ax)
    ax.set_xticklabels(min_dist.index.get_level_values(level=1).tolist(), rotation=0)
    
    for i in range(len(min_dist)):
        if i == 0: #For A label
            ax.text(0.2, -0.1, min_dist.index.get_level_values(level=0)[0], ha='center', transform=ax.transAxes)
        elif i == 2: #For B label
            ax.text(0.6, -0.1, min_dist.index.get_level_values(level=0)[2], ha='center', transform=ax.transAxes)
        elif i == 4: #For C label
            ax.text(0.9, -0.1, min_dist.index.get_level_values(level=0)[4], ha='center', transform=ax.transAxes)
    plt.show()
    

    阴谋

    编辑:要仅在轴标签中显示品牌,您需要通过将xticklabels 更改为 [] 将第一级设置为空白。此外,由于第二层似乎与情节相去甚远。因此,您可以通过将位置从-0.1 减少到-0.05 来更接近轴。

    此外,只是为了好玩,我为每个品牌添加了不同的颜色。因此,A 将是红色,B 将是蓝色,C 将是绿色。如果不需要,请随意不使用该代码.. 或将mymap 中的颜色更改为您喜欢的颜色。

    更新代码

    min_dist=crs.groupby(by=['brand', 'mark']).agg({'milage': 'min'})
    
    ## Create new column and map colors to what you want in them
    mymap = {'A': 'red', 'B':'green', 'C':"blue"}
    min_dist['mycolor'] = min_dist.index.get_level_values(0).map(mymap)
    
    fig, ax = plt.subplots(figsize=(10,6))
    
    min_dist.milage.plot(kind='bar', xlabel='', color = mycolor, ax=ax)
    #ax.set_xticklabels(min_dist.index.get_level_values(level=1).tolist(), rotation=0)
    ax.set_xticklabels([]) ## Changed to blanks, so that first level will not be shown
    ax.legend().remove()
    
    for i in range(len(min_dist)):  ##Update - reduced y-spacing from -0.1 to -0.05
        if i == 0: #For A label
            ax.text(0.2, -0.05, min_dist.index.get_level_values(level=0)[0], ha='center', transform=ax.transAxes)
        elif i == 2: #For B label
            ax.text(0.6, -0.05, min_dist.index.get_level_values(level=0)[2], ha='center', transform=ax.transAxes)
        elif i == 4: #For C label
            ax.text(0.9, -0.05, min_dist.index.get_level_values(level=0)[4], ha='center', transform=ax.transAxes)
    
    plt.show()
    

    阴谋

    【讨论】:

    • 谢谢你。有没有办法使用数据框“min_dist”只显示品牌?当我尝试 min_dist.plot(x='brand', kind='bar') 时,我给了我关键错误'brand'。我知道如果我制作一个按品牌分组的数据框,我们只能显示品牌。但我希望将数据框按品牌和标记分组以供将来使用。
    • 更新回复...
    猜你喜欢
    • 2019-03-03
    • 1970-01-01
    • 2020-07-09
    • 2019-04-20
    • 2018-05-17
    • 2020-01-07
    • 1970-01-01
    • 2019-12-14
    • 2017-10-17
    相关资源
    最近更新 更多