【问题标题】:Matplotlib / Seaborn Countplot with different Categories in one PlotMatplotlib / Seaborn Countplot 在一个图中具有不同类别
【发布时间】:2018-03-11 21:57:48
【问题描述】:

我有两个具有不同长度和数量的变量的系列,并且想要绘制每个变量(名称)在每个系列中出现的频率。 我想要系列 1 的灰色计数图和系列 2 的红色计数图,并且我希望它们彼此重叠显示。 然而,由于系列 2 缺少“Nancy”,因此它也减少了系列 1 的“Nancy”计数。 我如何获得两个系列的完整覆盖,包括南希的酒吧?

import matplotlib.pyplot as plt
import seaborn as sns

ser1 = pd.Series( ['tom','tom','bob','bob','nancy'])
ser2 = pd.Series( ['tom','bob'])

fig = plt.figure()
sns.countplot(x=ser1, color='grey')
sns.countplot(x=ser2, color='red')
plt.show()

编辑: 更改为以下将再次导致问题。如何让 Matplotlib 识别这两个系列具有相同的分类值?

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

ser1 = pd.Series( ['tom','tom','bob','bob','nancy','zulu'])
ser2 = pd.Series( ['tom','nancy'])

ser1 = ser1.astype('category')
ser2 = ser2.astype('category')

fig = plt.figure()
ax = sns.countplot(x=ser2, color='red', zorder=2)
sns.countplot(x=ser1, color='grey')

plt.show()

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

    您可以存储第一个图的设置并在绘制第二个图后恢复它们。

    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    ser1 = pd.Series( ['tom','tom','bob','bob','nancy','zulu'])
    ser2 = pd.Series( ['tom','bob'])
    
    fig = plt.figure()
    ax = sns.countplot(x=ser1, color='grey')
    ticks = ax.get_xticks()
    ticklabels = ax.get_xticklabels()
    lim = ax.get_xlim()
    
    sns.countplot(x=ser2, color='red')
    ax.set_xlim(lim)
    ax.set_xticks(ticks)
    ax.set_xticklabels(ticklabels)
    plt.show()
    

    另一种选择可能是先绘制第二个图,但将 zorder 设置为更高的值,这样这些条形就会出现在后面的图之前。

    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    ser1 = pd.Series( ['tom','tom','bob','bob','nancy','zulu'])
    ser2 = pd.Series( ['tom','bob'])
    
    fig = plt.figure()
    ax = sns.countplot(x=ser2, color='red', zorder=2)
    sns.countplot(x=ser1, color='grey')
    
    plt.show()
    

    在更一般的情况下,您需要使用order 参数。

    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    ser1 = pd.Series( ['tom','tom','bob','bob','nancy', 'nancy' ,'zulu'])
    ser2 = pd.Series( ['tom','nancy'])
    order = ser1.append(ser2).unique()
    
    fig = plt.figure()
    ax = sns.countplot(x=ser2, color='red', order=order, zorder=2)
    sns.countplot(x=ser1, color='grey', order=order)
    
    plt.show()
    

    如果您更愿意使用 matplotlib 的分类来创建绘图,则如下所示:

    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    
    ser1 = pd.Series( ['tom','tom','bob','bob','nancy', 'nancy' ,'zulu'])
    ser2 = pd.Series( ['tom','nancy'])
    
    u1, counts1 = np.unique(ser1.values, return_counts=True)
    u2, counts2 = np.unique(ser2.values, return_counts=True)
    
    fig, ax = plt.subplots()
    ax.bar(u1,counts1, color='grey')
    ax.bar(u2,counts2, color='red')
    
    plt.show()
    

    【讨论】:

    • 感谢您的快速解决方案!我现在正在使用 zorder 技巧。
    • 不幸的是,matplotlib 无法识别类别。如果我将我的系列更改为: ser1 = pd.Series( ['tom','tom','bob','bob','nancy','zulu']) ser2 = pd.Series( ['tom', 'nancy']) 结果将不正确。即使系列 dtype('category')
    • 我用zulu更新了答案,它按预期工作。
    • 如果将 ser2 更改为 ser2 = pd.Series( ['tom','nancy']) 类别将不再匹配。
    • 我更新了答案。请注意,您在这里使用的是 seaborn countplot,因此这不使用 matplotlib 分类轴,而是 seaborn 在内部创建的数值轴。我还添加了一个 matplotlib 解决方案进行比较。
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    相关资源
    最近更新 更多