【问题标题】:Why are these barplots on top of each other?为什么这些条形图彼此重叠?
【发布时间】:2020-02-14 19:17:01
【问题描述】:

我正在尝试使用 matplotlib 创建子图,其中有 2 行和 3 列。我有一个数据框df,列AF。我希望每个子图都是AF 的每一列的条形图。

我确定这只是代码中的一个小错误,但我如何让它们在不同的子图中绘制而不是全部重叠?

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(4,15,size=(100, 6)), columns=list('ABCDEF'))
df['A'].value_counts()

rows, cols = 2,3
fig, ax = plt.subplots(rows, cols, sharex='col', sharey='row')

myplots = ['A','B','C','D','E','F']

for j in myplots:
    x = range(len(df[j].value_counts()))
    for row in range(2):
        for col in range(3):
            ax[row, col].bar(x, df[j].value_counts().sort_index())

【问题讨论】:

    标签: python pandas for-loop matplotlib


    【解决方案1】:

    IIUC,您想在单独的子图中绘制每列的值计数:

    (df.stack().groupby(level=1)
         .value_counts()
         .unstack(level=0)
         .plot.bar(layout=(2,3), subplots=True));
    

    输出:


    注意:回答您的问题为什么...

    for j in myplots:
        x = range(len(df[j].value_counts()))
        for row in range(2):
            for col in range(3):
    

    由于j 循环位于最外层,因此您可以有效地利用 每个子图上每列 (df[j]) 的值计数。这就是子图看起来相同的原因。

    要使您的解决方案有效,请使用zip

    rows, cols = 2,3
    fig, axes = plt.subplots(rows, cols, sharex='col', sharey='row')
    
    myplots = ['A','B','C','D','E','F']
    
    for j, ax in zip(myplots, axes.ravel()):
        df[j].value_counts(sort=False).plot.bar(ax=ax)
    

    输出:

    【讨论】:

    • 正确,我想实际使用for循环。你认为有办法让我的代码在上面工作吗?
    【解决方案2】:

    这样的? (在我看来,这是解决索引的错误)

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    
    df = pd.DataFrame(np.random.randint(4,15,size=(100, 6)), columns=list('ABCDEF')).  #  (100,6)
    df['A'].value_counts()
    
    rows, cols = 2,3
    fig, ax = plt.subplots(rows, cols, sharex='col', sharey='row')
    
    myplots = ['A','B','C','D','E','F']
    
    #for j in myplots:
        #x = range(len(df[j].value_counts()))
    for row in range(2):
        for col in range(3):
            ind = row*3+col  # here it is
            # ax[row, col].bar(list(range(len(df['A']))), df[myplots[ind]])
    
            set_of_values = df[myplots[ind]].value_counts()
            count_of_values = df[myplots[ind]].value_counts().sort_index()        
            ax[row, col].bar(set_of_values, count_of_values)
    
            ax[row,col].set_xlabel(myplots[ind])
    

    【讨论】:

    • 代码的value_counts() 部分发生了什么?当我为我的数据尝试您的代码时,它只会绘制所有原始数据。
    • 请注意,我已将数据帧(第 5 行代码)中矩阵的维度从 (100,6) 更改为 (10,6),以使绘图更具可读性。可能是这个原因
    • 不是这样的。原始数据框的长度应为 100 多行。最后需要绘制的是:df[j].value_counts().sort_index()返回一系列唯一值而不是原始数据。
    • 你的子图看起来不错,但我不认为它实际上是在绘制我想要的。
    • 我已经更新了。现在它计算并绘制唯一值
    猜你喜欢
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    相关资源
    最近更新 更多