python - Pandas 堆积条形图中元素的排序

标签 python pandas matplotlib plot

我正在尝试绘制有关一个地区 5 个地区的特定行业的家庭收入部分的信息。

我使用 groupby 按地区对数据框中的信息进行排序:

df = df_orig.groupby('District')['Portion of income'].value_counts(dropna=False)
df = df.groupby('District').transform(lambda x: 100*x/sum(x))
df = df.drop(labels=math.nan, level=1)
ax = df.unstack().plot.bar(stacked=True, rot=0)
ax.set_ylim(ymax=100)

display(df.head())

    District  Portion of income
    A         <25%                 12.121212
              25 - 50%              9.090909
              50 - 75%              7.070707
              75 - 100%             2.020202

由于此收入属于类别,因此我想以合乎逻辑的方式对堆叠条中的元素进行排序。 Pandas 生成的图表如下。现在,顺序(从每个条形的底部开始)是:
  • 25 - 50%
  • 50 - 75%
  • 75 - 100%
  • <25%
  • 不确定

  • 我意识到这些是按字母顺序排序的,并且很好奇是否有办法设置自定义排序。为了直观,我希望顺序是(同样,从栏的底部开始):
  • 不确定
  • <25%
  • 25 - 50%
  • 50 - 75%
  • 75 - 100%



  • 然后,我想翻转图例以显示与此顺序相反的顺序(即,我希望图例顶部有 75 - 100,因为这将位于条形图的顶部)。

    最佳答案

    要对收入类别施加自定义排序顺序,一种方法是将它们转换为 CategoricalIndex .

    要反转 matplotlib 图例条目的顺序,请使用 get_legend_handles_labels来自这个问题的方法:Reverse legend order pandas plot

    import pandas as pd
    import numpy as np
    import math
    
    np.random.seed(2019)
    
    # Hard-code the custom ordering of categories
    categories = ['unsure', '<25%', '25 - 50%', '50 - 75%', '75 - 100%']
    
    # Generate some example data
    # I'm not sure if this matches your input exactly
    df_orig = pd.DataFrame({'District': pd.np.random.choice(list('ABCDE'), size=100), 
                            'Portion of income': np.random.choice(categories + [np.nan], size=100)})
    
    # Unchanged from your code. Note that value_counts() returns a 
    # Series, but you name it df
    df = df_orig.groupby('District')['Portion of income'].value_counts(dropna=False)
    df = df.groupby('District').transform(lambda x: 100*x/sum(x))
    
    # In my example data, np.nan was cast to the string 'nan', so 
    # I have to drop it like this
    df = df.drop(labels='nan', level=1)
    
    # Instead of plotting right away, unstack the MultiIndex
    # into columns, then convert those columns to a CategoricalIndex 
    # with custom sort order
    df = df.unstack()
    
    df.columns = pd.CategoricalIndex(df.columns.values, 
                                     ordered=True, 
                                     categories=categories)
    
    # Sort the columns (axis=1) by the new categorical ordering
    df = df.sort_index(axis=1)
    
    # Plot
    ax = df.plot.bar(stacked=True, rot=0)
    ax.set_ylim(ymax=100)
    
    # Matplotlib idiom to reverse legend entries 
    handles, labels = ax.get_legend_handles_labels()
    ax.legend(reversed(handles), reversed(labels))
    

    Output

    关于python - Pandas 堆积条形图中元素的排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54874269/

    相关文章:

    python - 尝试使用Docker访问MongoDB时,连接被拒绝[Errno 111]

    python - 如何在 Pandas 中的超大数据帧上创建数据透视表

    python - 如果MSSQL查询为空,如何删除空白表?

    python - 具有可扩展/可更新 x 轴的 Matplotlib 图

    python-3.x - 我怎样才能在我的情节标题中正确地格式化这个方程式? ( python 3)

    python - 在 PyMongo 中使用正则表达式动态构建查询

    python - 将包含分组数据的 CSV 导入到 Pandas 数据框中

    python - reshape Pandas Dataframe 的最佳方式

    python - 在 Matplotlib/Cartopy 中制作颜色条图例

    python - 重置 time.clock()