使用matplotlib在一个图中绘制多个直方图

4

我需要在帮助类中编写一个函数的代码,它将在一个图形中绘制多个直方图。使用我下面的代码,我得到了ValueError:too many values to unpack,这是由于for命令行中的变量数多于值,或者与之相反。我做错了什么?

def draw_histograms(df, variables, n_rows, n_cols):
    fig = plt.figure()
    for n_rows, n_cols, plot_number in df:
        fig.add_subplot(n_rows, n_cols, plot_number)
    plt.show()

        """ variables includes a list of variables you need to draw histograms for. 
n_rows and n_cols specifies the number of subplots you need to have in a figure. 
If n_rows =3 and n_cols =2, there will 3*2 = 6 subplots placed in a grid of 3 rows and 2 columns.
subplot(321) is identical to subplot(3,2,1), which refers to the 1st subplot in a grid of 3 rows and 2 columns"""

util.draw_histograms(df, variables = ['DerogCnt', 'CollectCnt', 'InqCnt06', 'InqTimeLast', 'InqFinanceCnt24', 'TLTimeFirst', 'TLTimeLast', 'TLCnt03', 'TLCnt12'], 3,3) 

这是 df 的样子。由于不相关的变量已被删除,所以变量并不包括全部内容。
TARGET   ID  DerogCnt  CollectCnt  BanruptcyInd  InqCnt06  InqTimeLast  \
0       0   66         1           1             0         7            1   
1       0  116         1           1             0         2            1   
2       0  124         0           0             0         1            1   
3       0  128         0           0             0         6            3   
4       0  143         0           0             0         1            0   
   InqFinanceCnt24  TLTimeFirst  TLTimeLast     ...       TL50UtilCnt  \
0                4          125           3     ...                 4   
1                0          252          18     ...                 2   
2                4          254          12     ...                 3   
3                6          154           3     ...                 5   
4                1          311          17     ...                 3   

   TLBalHCPct  TLSatPct  TLDel3060Cnt24  TLDel90Cnt24  TLDel60CntAll  \
0        0.85      0.67               0             0              1   
1        0.48      0.30               0             1              4   
2        0.84      0.67               0             1              1   
3        0.73      0.76               0             1              1   
4        0.88      0.63               0             0              1   

   TLOpenPct  TLBadDerogCnt  TLDel60Cnt24  TLOpen24Pct  
0       0.58              0             0         0.71  
1       0.40              2             1         0.50  
2       0.50              1             1         0.33  
3       0.53              1             1         1.22  
4       0.63              0             0         0.20  

这里是


2
你没有展示df中的内容,所以我们无法判断。顺便说一下,在你的函数“draw_histograms”中没有使用变量。 - roadrunner66
1个回答

4

这里不是三个,而只有一个变量需要“解包”,因此会出现错误(详见下文)。您可能可以不使用for循环,因为df.hist()有一个layout参数,允许您使用(n_row, n_col)参数定义相同的布局。

df = pd.DataFrame(data=np.random.random(size=(50, 6)), columns=[i for i in string.ascii_lowercase[:6]])
df.hist(layout=(3,2))
plt.show()

enter image description here

当您在for循环中迭代df时:
for n_rows, n_cols, plot_number in df:

df每次迭代仅返回单个值,即column名称。

例如:

df = pd.DataFrame(data=np.random.random(size=(5, 5)), columns=[i for i in string.ascii_lowercase[:5]])

print([i for i in df])

['a', 'b', 'c', 'd', 'e']

由于n_rows、n_cols和plot_number表示在每次迭代中将解包三个值,因此引发了ValueError。使用for ... in df.items(),您将获得两个值-列名和数据:
for i, col in df.items():
    print('\n', i)
    print(col)

 a
0    0.640400
1    0.683003
2    0.807806
3    0.767698
4    0.648523
Name: a, dtype: float64

 b
0    0.774166
1    0.052386
2    0.235688
3    0.018334
4    0.492798
Name: b, dtype: float64

 c
0    0.390146
1    0.383680
2    0.588734
3    0.911859
4    0.901137
Name: c, dtype: float64

 d
0    0.455289
1    0.626278
2    0.977627
3    0.311236
4    0.570580
Name: d, dtype: float64

 e
0    0.782046
1    0.041161
2    0.226500
3    0.331402
4    0.942302
Name: e, dtype: float64

这是我现在遇到的 ValueError: ValueError: Layout of 3x3 must be larger than required size 30。如果使用 df.hist(layout=(15,2)),它就能正常工作,因为 15X2 是 30。我应该实现一个 assert 或 error 函数吗?如果需要,有什么建议吗?谢谢! - squidvision
1
您可以动态生成布局,但无论如何都需要与图表数量匹配。如何实现取决于您的场景多样性程度。如果可用选项较少,例如 {6: (3,2), 10: (5,5), 15: (5, 3)} 等,您可以使用 dictionary 来创建布局, 如 layout=(layout_dict[num_charts]) 。抱歉回复晚了! - Stefan
你需要在matplotlib中制作直方图时使用pandas吗?这真的必要吗? - stelios

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