使用pandas和matplotlib绘制分类数据的图表

142

我有一个包含分类数据的数据框:

     colour  direction
1    red     up
2    blue    up
3    green   down
4    red     left
5    red     right
6    yellow  down
7    blue    down

我想根据分类生成一些图表,如饼图和直方图。是否可以在不创建虚拟数值变量的情况下实现?就像这样:

df.plot(kind='hist')
9个回答

263

你可以直接在该系列上使用value_counts

df['colour'].value_counts().plot(kind='bar')

enter image description here


1
建议使用 df["colour"].value_counts().plot(kind='bar') 作为常见的替代方案。 - openwonk
2
能否指定 x 标签的顺序? - P. Camilleri
4
是的,你可以明确指定x轴标签的顺序,例如:df['colour'].value_counts()[['green', 'yellow', 'blue', 'red']] - Alexander
请问您如何调整这个图表呢?比如说,如果我想为每个类别更改颜色,或者我想添加一个图例,应该怎么做呢? - Ibtihaj Tahir
1
现在,语法df["colour"].value_counts().plot().bar()更加Pandarific - 但这让我免去了一些痛苦!谢谢! - mishaF

28

你可能会发现 mosaic 统计模型的图形化表示很有用,它还可以为差异提供统计突出显示。

from statsmodels.graphics.mosaicplot import mosaic
plt.rcParams['font.size'] = 16.0
mosaic(df, ['direction', 'colour']);

在此输入图片描述

但要注意0大小的单元格,它们会导致标签问题。

有关详细信息,请参见此答案


感谢。我不断收到“ValueError:无法将NA转换为整数”的错误。 - Ivan
1
这就是为什么我引用了这个答案。它应该有助于解决这个问题。 - Primer

24

像这样:

df.groupby('colour').size().plot(kind='bar')

19
你还可以使用seaborn中的countplot。该包基于pandas构建,创建了一个高级绘图接口。它为你提供良好的样式和正确的坐标轴标签。
import pandas as pd
import seaborn as sns
sns.set()

df = pd.DataFrame({'colour': ['red', 'blue', 'green', 'red', 'red', 'yellow', 'blue'],
                   'direction': ['up', 'up', 'down', 'left', 'right', 'down', 'down']})
sns.countplot(df['colour'], color='gray')

enter image description here

它还支持通过一些小技巧以正确的颜色着色条形图

sns.countplot(df['colour'],
              palette={color: color for color in df['colour'].unique()})

enter image description here


你好。我该如何修改变量的名称?例如,我有近10个变量类别,当我制作这个图表时,名称会重叠在一起。我该怎么做才能避免这种情况发生?我应该增加figsize或其他什么吗? - Mahreen Athar

14

如果要在同一张图中绘制多个分类特征的条形图,我建议:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    {
        "colour": ["red", "blue", "green", "red", "red", "yellow", "blue"],
        "direction": ["up", "up", "down", "left", "right", "down", "down"],
    }
)

categorical_features = ["colour", "direction"]
fig, ax = plt.subplots(1, len(categorical_features))
for i, categorical_feature in enumerate(df[categorical_features]):
    df[categorical_feature].value_counts().plot("bar", ax=ax[i]).set_title(categorical_feature)
fig.show()

插入图片描述


6
您可以使用选项设置为Falsevalue_counts函数,这样可以保留类别的顺序。
df['colour'].value_counts(sort=False).plot.bar(rot=0)

link to image


3

Pandas.Series.plot.pie

https://pandas.pydata.org/docs/reference/api/pandas.Series.plot.pie.html

在不离开内置功能的情况下,我们可以比这更好。

人们常常对饼图提出质疑,但它们与马赛克图/树状图具有相同的优点:帮助保持整体比例的可读性。

kwargs = dict(
    startangle = 90,
    colormap   = 'Pastel2',
    fontsize   = 13,
    explode    = (0.1,0.1,0.1),
    figsize    = (60,5),
    autopct    = '%1.1f%%',
    title      = 'Chemotherapy Stratification'
)

df['treatment_chemo'].value_counts().plot.pie(**kwargs)

enter image description here


2
使用plotly
import plotly.express as px
px.bar(df["colour"].value_counts())

2

Roman的回答非常有帮助且正确,但在最新版本中,您还需要指定类型(kind)作为参数的顺序可能会改变。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    {
    "colour": ["red", "blue", "green", "red", "red", "yellow", "blue"],
    "direction": ["up", "up", "down", "left", "right", "down", "down"],
    }
)

categorical_features = ["colour", "direction"]
fig, ax = plt.subplots(1, len(categorical_features))
for i, categorical_feature in enumerate(df[categorical_features]):
    df[categorical_feature].value_counts().plot(kind="bar", ax=ax[i]).set_title(categorical_feature)
fig.show()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接