为什么这些条形图相互重叠?

时间:2019-10-17 19:56:30

标签: python pandas for-loop matplotlib

我正在尝试使用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())

enter image description here

2 个答案:

答案 0 :(得分:1)

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

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

输出:

enter image description here


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

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)

输出:

enter image description here

答案 1 :(得分:0)

像这样? (我认为这是索引求解中的错误)

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])

enter image description here