【问题标题】:Matplotlib not respecting Pandas categorical value orderMatplotlib 不尊重 Pandas 分类值顺序
【发布时间】:2022-01-27 06:31:16
【问题描述】:

我有一个简单的数据框,其中一列 SIZE 为分类值(SMALL、MEDIUM、LARGE),另一列 VALUE 为整数。当我创建一个 VALUE 作为 SIZE 函数的散点图时,X 轴上显示的类别的顺序会发生变化,具体取决于数据框中第一行的 SIZE。我确保告诉 Pandas SIZE 类别值的明确“排序”。

要查看实际情况,请使用以下代码 sn-p

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'SIZE': ['MEDIUM', 'MEDIUM', 'LARGE', 'SMALL', 'LARGE', 'LARGE'], 
                   'VALUE': [1, 2, 3, 4, 5, 6]})

# Convert to categorical data type and define the order
df['SIZE'] = pd.Categorical(df['SIZE'], categories=['SMALL', 'MEDIUM', 'LARGE'], ordered=True)

print(df.dtypes)
print(df)
print(df.SIZE.describe)

这会产生以下输出:

SIZE     category
VALUE       int64
dtype: object

     SIZE  VALUE
0  MEDIUM      1
1  MEDIUM      2
2   LARGE      3
3   SMALL      4
4   LARGE      5
5   LARGE      6

<bound method NDFrame.describe of 0    MEDIUM
1    MEDIUM
2     LARGE
3     SMALL
4     LARGE
5     LARGE
Name: SIZE, dtype: category
Categories (3, object): ['SMALL' < 'MEDIUM' < 'LARGE']>

看看这个,似乎一切都很好。但是当我使用

fig, ax = plt.subplots()
ax.scatter(df.SIZE, df.VALUE)

我得到一个图表,其中 X 轴上的第一个类别是“中”,而不是“小”。

如果我只是将第一行的 SIZE 更改为“小”,即

df = pd.DataFrame({'SIZE': ['SMALL', 'MEDIUM', 'LARGE', 'SMALL', 'LARGE', 'LARGE'], 
                   'VALUE': [1, 2, 3, 4, 5, 6]})

然后重新运行其余代码,我将得到一个具有正确顺序的图表。

我显然错过了 Matplotlib 中的一些细微差别。我正在使用 Matplotlib 3.4.3 和 Pandas 1.3.4。

【问题讨论】:

    标签: python pandas matplotlib


    【解决方案1】:

    Matplotlib 不关心 Categorical dtype。您应该首先按SIZE 对数据框进行排序:

    fig, ax = plt.subplots()
    df = df.sort_values('SIZE')
    ax.scatter(df.SIZE, df.VALUE)
    plt.show()
    

    【讨论】:

    • 这是有道理的。有趣的是,使用 Pandas 进行绘图,例如df.plot.scatter('SIZE', 'VALUE') 具有相同的行为 - Pandas 确实知道分类 dtype,但显然不关心顺序。 Seaborn 做对了并保持了秩序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 2018-10-12
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多