简体   繁体   English

如何在带有熊猫的条形图中绘制堆叠的一维和一个法线?

[英]How do I plot one dimension as stacked and one normal in a bar graph with pandas?

I would like to plot a bar graph, using pandas, that two categorical variables and 5 numeric columns. 我想绘制一个使用熊猫的条形图,其中包含两个分类变量和5个数字列。 I would like to first group by one categorical variable and show the sum as grouped bars. 我想先按一个分类变量分组,然后将总和显示为分组的条。 I would also like to group by the second categorical variable, and have each bar show the second category as stacked bars. 我还想按第二个类别变量分组,并让每个栏将第二个类别显示为堆叠栏。

A sample dataframe like mine can be constructed as follows: 像我的样例数据帧可以构造如下:

import pandas as pd
l=100
df = pd.DataFrame({'op1': [random.randint(0,1) for x in range(l)], 
                    'op2': [random.randint(0,1) for x in range(l)], 
                    'op3': [random.randint(0,1) for x in range(l)], 
                    'op4': [random.randint(0,1) for x in range(l)], 
                    'op5': [random.randint(0,1) for x in range(l)],
                    'cat': random.choices(list('abcde'), k=l),
                    'gender': random.choices(list('mf-'), k=l)})
df.head()

  cat gender  op1  op2  op3  op4  op5
0   d      m    1    1    1    1    1
1   a      m    1    1    0    0    1
2   b      -    1    0    1    0    1
3   c      m    0    1    0    0    0
4   b      -    0    0    1    1    0
5   c      f    1    1    1    1    1
6   a      -    1    1    0    1    0
7   d      f    1    0    1    0    1
8   d      m    1    1    0    1    0
9   b      -    1    0    1    0    0

I can produce the grouped bar easily enough: df.groupby('cat')[['op%s' % i for i in range(1,6)]].sum().plot.bar() 我可以很容易地产生分组的条: df.groupby('cat')[['op%s' % i for i in range(1,6)]].sum().plot.bar()

But how can I get each bar to show the gender breakdown? 但是,如何获得每个栏来显示性别细分?

Inspired by the thread the vbox pointed me to, I implemented it using a series of subplots, and mucking around with the color. 受vbox指向我的线程的启发,我使用了一系列子图来实现它,然后对颜色进行处理。 It is pretty kludgy, and if anyone wants to use this with a more variable dataset, they'll need to address some concerns, but posting here in case it is helpful. 这很繁琐,如果有人想将它与更多可变的数据集一起使用,他们将需要解决一些问题,但如果有帮助,请在此处发布。

import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import random

l=100
df = pd.DataFrame({'op1': [random.randint(0,1) for x in range(l)], 
                    'op2': [random.randint(0,1) for x in range(l)], 
                    'op3': [random.randint(0,1) for x in range(l)], 
                    'op4': [random.randint(0,1) for x in range(l)], 
                    'op5': [random.randint(0,1) for x in range(l)],
                    'cat': random.choices(list('abcde'), k=l),
                   'gender': random.choices(list('mf'), k=l)})

# grab the colors in the current setup (could just use a new cycle instead)
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']

values = df['cat'].unique()
l = len(values)

# make one subplot for every possible value
fig, axes = plt.subplots(1, l, sharey=True)

for i, value in enumerate(values):
    ax = axes[i]

    # make a dataset that includes gender and all options, then change orientation
    df2 = df[df['cat'] == value][['gender', 'op1', 'op2', 'op3', 'op4', 'op5']].groupby('gender').sum().transpose()

    # do the stacked plot. 
    # Note this has all M's one color, F's another
    # but we want each bar to have its own colour scheme
    df2.plot.bar(stacked=True, width=1, ax=ax, legend=False)

    # kludge to change bar colors
    # Note: this won't work if one gender is not present
    # or if there is a 3rd option for gender, as there is in the sample data
    # for this example, I've changed gender to just be m/f
    bars = [rect for rect in ax.get_children() if isinstance(rect, mpl.patches.Rectangle)]
    for c, b in enumerate(bars[:len(df2)*2]):
        b.set_color(colors[c%len(df2)])
        if c >= len(df2):
            b.set_alpha(0.5)

    ax.spines["top"].set_visible(False)   
    ax.spines["bottom"].set_color('grey')
    ax.spines["right"].set_visible(False)  
    ax.spines["left"].set_visible(False) 
    ax.set_xticks([])
    ax.set_xlabel(value, rotation=45)

输出看起来像什么

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 python 中绘制条形 plot 时,如何在 3 列的 pandas 数据框中将其堆叠为 2 列而不是为一列堆叠? - While plotting bar plot in python, how can I make it stacked for 2 columns and not stacked for one column in a pandas data frame of 3 columns? 如何将条形 plot 和密度 plot 与 pandas 合并 - How do you merge a bar plot and a density plot in one with pandas 如何使用Pandas绘制条形图? - How do I plot a bar graph using Pandas? 如何在一个具有相同颜色但不同线条样式的图形中绘制两个pandas DataFrame? - How do I plot two pandas DataFrames in one graph with the same colors but different line styles? 如何在 matplotlib 中的一个图上从 Pandas 数据框中添加多个条形图? - How do I add multiple bar graphs from a pandas dataframe on one plot in matplotlib? 一列python中的堆积条形图 - stacked bar plot in plotly in one column python 我如何在一张图中 plot 10 正态分布(包括示例图片) - How can I plot 10 normal distribution in one graph ( example picture included) 从两个熊猫groupby对象绘制堆叠的条形图? - Plot a stacked bar graph from two pandas groupby objects? 在熊猫中,我如何只绘制一组? - In Pandas how do i plot for one group only? 如何在 Python 中获得一个分组条形图,其中一个条是堆叠的,而其他条不是? - How to get a grouped bar plot in Python in which one of the bar is stacked and the others are not?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM