Python 如何绘制计数条形图,用一个分类列进行分组,用另一个分类列进行着色

Python 如何绘制计数条形图,用一个分类列进行分组,用另一个分类列进行着色,python,pandas,Python,Pandas,我有一个大致如下的数据框: Property Name industry 1 123 name1 industry 1 1 144 name1 industry 1 2 456 name2 industry 1 3 789 name3 industry 2 4 367 name4 industry 2 . ... ... ... . ... ... ... n

我有一个大致如下的数据框:

  Property   Name    industry
1  123     name1    industry 1
1  144     name1    industry 1
2  456     name2    industry 1
3  789     name3    industry 2
4  367     name4    industry 2
.  ...     ...      ... 
.  ...     ...      ... 
n  123     name1    industry 1
ax = df['name'].value_counts().plot(kind='bar',
                                    figsize=(14,8),
                                    title="Number for each Owner Name")
ax.set_xlabel("Owner Names")
ax.set_ylabel("Frequency")
我想做一个条形图,绘制每个名称的行数,并根据行业对条形图进行着色。我试过这样的方法:

  Property   Name    industry
1  123     name1    industry 1
1  144     name1    industry 1
2  456     name2    industry 1
3  789     name3    industry 2
4  367     name4    industry 2
.  ...     ...      ... 
.  ...     ...      ... 
n  123     name1    industry 1
ax = df['name'].value_counts().plot(kind='bar',
                                    figsize=(14,8),
                                    title="Number for each Owner Name")
ax.set_xlabel("Owner Names")
ax.set_ylabel("Frequency")
我得到以下信息:

我的问题是如何根据数据框中的行业列(并添加图例)为条形图着色


谢谢

这可能有点太复杂了,但这样就行了。我首先定义了从名称到行业以及从行业到颜色的映射(似乎只有两个行业,但您可以根据自己的情况调整字典):

然后可以使用上述两个映射生成颜色:

c = df['Name'].value_counts().index.map(lambda x: ind_col_map[name_ind_map[x]])
最后,只需将
颜色
添加到绘图功能中即可:

ax = df['Name'].value_counts().plot(kind='bar',
                                    figsize=(14,8),
                                    title="Number for each Owner Name", color=c)
ax.set_xlabel("Owner Names")
ax.set_ylabel("Frequency")
plt.show()

让我们使用一些数据帧重塑和matplotlib:

ax = df.groupby(['industry','Name'])['Name'].count().unstack(0).plot.bar(title="Number for each Owner Name", figsize=(14,8))
_ = ax.set_xlabel('Owner')
_ = ax.set_ylabel('Frequency')
输出:

这是我的答案:

def plot_bargraph_with_groupings(df, groupby, colourby, title, xlabel, ylabel):
    """
    Plots a dataframe showing the frequency of datapoints grouped by one column and coloured by another.
    df : dataframe
    groupby: the column to groupby
    colourby: the column to color by
    title: the graph title
    xlabel: the x label,
    ylabel: the y label
    """

    import matplotlib.patches as mpatches

    # Makes a mapping from the unique colourby column items to a random color.
    ind_col_map = {x:y for x, y in zip(df[colourby].unique(),
                               [plt.cm.Paired(np.arange(len(df[colourby].unique())))][0])}


    # Find when the indicies of the soon to be bar graphs colors.
    unique_comb = df[[groupby, colourby]].drop_duplicates()
    name_ind_map = {x:y for x, y in zip(unique_comb[groupby], unique_comb[colourby])}
    c = df[groupby].value_counts().index.map(lambda x: ind_col_map[name_ind_map[x]])

    # Makes the bargraph.
    ax = df[groupby].value_counts().plot(kind='bar',
                                         figsize=FIG_SIZE,
                                         title=title,
                                         color=[c.values])
    # Makes a legend using the ind_col_map
    legend_list = []
    for key in ind_col_map.keys():
        legend_list.append(mpatches.Patch(color=ind_col_map[key], label=key))

    # display the graph.
    plt.legend(handles=legend_list)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
使用seaborn.countplot

import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
ax = sns.countplot(x="class", data=titanic)
请参阅seaborn的文档

这是可行的,但我的df中有13个类别,这会将这些栏隔开,使它们看起来非常小。有没有办法解决这个问题?我该如何用这个来制作一个传奇?@tlanigan你可以用与matplotlib完全相同的方法来做。我认为Scott Boston的答案要好得多,我的答案太手动了。Scott Boston的答案不适合我,因为这些列被隔开了。您可以使用:ind_col_map={x:y代表x,y在zip(df.industry.unique(),[plt.cm.Paired(np.arange(len(df.industry.unique())))][0])中自动完成答案。您如何在matplotlib中创建图例?我一直在努力,但我想不出来。我在下面找到了。你如何显示每列的实际计数???