Matplotlib 堆叠直方图 numpy.ndarray 错误

Matplotlib stacked histogram numpy.ndarray error

我正在尝试使用 matplotlib 制作堆叠直方图,方法是循环遍历数据框中的类别并根据字典分配条形颜色。

我在 ax1.hist() 调用中收到此错误。我该如何解决? AttributeError: 'numpy.ndarray' object has no attribute 'hist'

可重现的例子

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
%matplotlib inline
plt.style.use('seaborn-whitegrid')

y = [1,5,9,2,4,2,5,6,1]
cat = ['A','B','B','B','A','B','B','B','B']
df = pd.DataFrame(list(zip(y,cat)), columns =['y', 'cat'])

fig, axes = plt.subplots(3,3, figsize=(5,5), constrained_layout=True)
fig.suptitle('Histograms')
ax1 = axes[0]

mycolorsdict = {'A':'magenta', 'B':'blue'}
for key, batch in df.groupby(['cat']):
    ax1.hist(batch.y, label=key, color=mycolorsdict[key],
    density=False, cumulative=False, edgecolor='black',
    orientation='horizontal', stacked=True)

更新后的努力,仍然无效

这很接近,但不是堆叠(应该看到 y=5 处的堆叠);我想可能是因为循环?

mycolorsdict = {'A':'magenta', 'B':'blue'}
for ii, ax in enumerate(axes.flat):
    for key, batch in df.groupby(['cat']):
        ax.hist(batch.y, 
        label=key, color=mycolorsdict[key],density=False, edgecolor='black',
        cumulative=False, orientation='horizontal', stacked=True)

要绘制特定的子图,需要两个索引(行、列),因此第一个子图 axes[0,0]。错误消息来自使用 ax1 = axes[0] 而不是 ax1 = axes[0,0]

现在,要通过 ax.hist() 创建堆叠直方图,需要同时提供所有 y 数据。下面的代码显示了如何从 groupby 的结果开始执行此操作。另请注意,当您的值是离散的时,明确设置 bin 边界以确保值恰好落在这些边界之间非常重要。将边界设置在一半是一种方法。

使用 seaborn 的 histplot() 可以大大简化事情。以下是所用参数的细分:

  • data=df 数据帧
  • y='y' 给出直方图的数据框列。使用 x=(而不是 y=)作为垂直直方图。
  • hue='cat' 给出数据框列以创建多个组
  • palette=mycolorsdict;调色板定义颜色;有很多方法可以分配调色板,其中一种是 hue
  • 上的字典
  • discrete=True:当处理离散数据时,seaborn 设置适当的 bin 边界
  • multiple='stack' 根据 hue 类别创建堆叠直方图
  • alpha=1:seaborn 默认设置 alpha 为 0.75;可选地,这可以改变
  • ax=axes[0, 1]:在第 1st
  • 的第 2nd 子图中绘制
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

plt.style.use('seaborn-whitegrid')

y = [1, 5, 9, 2, 4, 2, 5, 6, 1]
cat = ['A', 'B', 'B', 'B', 'A', 'B', 'B', 'B', 'B']
df = pd.DataFrame({'y':y, 'cat':cat})

fig, axes = plt.subplots(3, 3, figsize=(20, 10), constrained_layout=True)
fig.suptitle('Histograms')

mycolorsdict = {'A': 'magenta', 'B': 'blue'}
groups = df.groupby(['cat'])
axes[0, 0].hist([batch.y for _, batch in groups],
                label=[key for key, _ in groups], color=[mycolorsdict[key] for key, _ in groups], density=False,
                edgecolor='black',
                cumulative=False, orientation='horizontal', stacked=True, bins=np.arange(0.5, 10))
axes[0, 0].legend()

sns.histplot(data=df, y='y', hue='cat', palette=mycolorsdict, discrete=True, multiple='stack', alpha=1, ax=axes[0, 1])

plt.show()