【问题标题】:Creating a boxplot FacetGrid in Seaborn for python在 Seaborn 中为 python 创建一个箱线图 FacetGrid
【发布时间】:2019-02-27 13:51:09
【问题描述】:

我正在尝试在 seaborn 中为 4 个箱线图创建一个 4x4 FacetGrid,每个箱线图根据 iris 数据集中的虹膜种类分为 3 个箱线图。目前,我的代码如下所示:

sns.set(style="whitegrid")
iris_vis = sns.load_dataset("iris")

fig, axes = plt.subplots(2, 2)

ax = sns.boxplot(x="Species", y="SepalLengthCm", data=iris, orient='v', 
    ax=axes[0])
ax = sns.boxplot(x="Species", y="SepalWidthCm", data=iris, orient='v', 
    ax=axes[1])
ax = sns.boxplot(x="Species", y="PetalLengthCm", data=iris, orient='v', 
    ax=axes[2])
ax = sns.boxplot(x="Species", y="PetalWidthCm", data=iris, orient='v', 
    ax=axes[3])

但是,我的解释器收到此错误:

AttributeError: 'numpy.ndarray' object has no attribute 'boxplot'

我对属性错误的确切位置感到困惑。我需要改变什么?

【问题讨论】:

    标签: python data-visualization seaborn data-science boxplot


    【解决方案1】:

    axes 形状为(nrows, ncols)。在这种情况下是:

    array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7f4267f425f8>,
            <matplotlib.axes._subplots.AxesSubplot object at 0x7f4267f1bb38>],
           [<matplotlib.axes._subplots.AxesSubplot object at 0x7f4267ec95c0>,
            <matplotlib.axes._subplots.AxesSubplot object at 0x7f4267ef9080>]],
          dtype=object)
    

    所以,当您执行ax=axes[0] 时,您会得到一个数组而不是轴。试试:

    fig, axes = plt.subplots(2, 2)
    
    ax = sns.boxplot(x="Species", y="SepalLengthCm", data=iris, orient='v', 
        ax=axes[0, 0])
    ax = sns.boxplot(x="Species", y="SepalWidthCm", data=iris, orient='v', 
        ax=axes[0, 1])
    ax = sns.boxplot(x="Species", y="PetalLengthCm", data=iris, orient='v', 
        ax=axes[1, 0])
    ax = sns.boxplot(x="Species", y="PetalWidthCm", data=iris, orient='v', 
        ax=axes[1, 1])
    

    【讨论】:

      【解决方案2】:

      因为@Lucas 指出轴返回 2D(nrows, ncols) 的 numpy 数组,所以您可以使用以下方法展平该数组:

      axes=axes.flatten()
      

      而且,您可以像这样保留相同的代码:

      fig, axes = plt.subplots(2, 2)
      axes = axes.flatten()
      
      ax = sns.boxplot(x="Species", y="SepalLengthCm", data=iris, orient='v', 
          ax=axes[0])
      ax = sns.boxplot(x="Species", y="SepalWidthCm", data=iris, orient='v', 
          ax=axes[1])
      ax = sns.boxplot(x="Species", y="PetalLengthCm", data=iris, orient='v', 
          ax=axes[2])
      ax = sns.boxplot(x="Species", y="PetalWidthCm", data=iris, orient='v', 
          ax=axes[3])
      

      输出:

      【讨论】:

        【解决方案3】:

        或者只是让上面的内容更简洁:

        cat_variables = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']
        x_var = "Species"
        fig, axes = plt.subplots(len(cat_variables)/2, len(cat_variables)/2, figsize=(15,15))
        axes = axes.flatten()
        
        i = 0
        for t in cat_variables:
            ax = sns.boxplot(x=x_var, y=TARGET, data=iris, orient='v', 
            ax=axes[i])
            i +=1
        

        【讨论】:

        • 获取错误:TypeError: 'float' object cannot be interpreted as an integer
        【解决方案4】:

        不是直接回答你的错误,但如果你打算使用 seaborn,你应该尝试坚持使用“长”或“整洁”的数据 (https://seaborn.pydata.org/tutorial/data_structure.html#long-form-data)。

        我假设您的原始数据集很宽(观察的每个特征的列)。如果你像这样融化数据集:

        iris = iris.melt(id_vars='target')
        
        print(iris.head())
        
           target           variable  value
        0  setosa  sepal length (cm)    5.1
        1  setosa  sepal length (cm)    4.9
        2  setosa  sepal length (cm)    4.7
        3  setosa  sepal length (cm)    4.6
        4  setosa  sepal length (cm)    5.0
        

        您将能够使用 seaborn 的 catplot 和 kind='box'

        sns.catplot(
            data=iris, x='target', y='value',
            col='variable', kind='box', col_wrap=2
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-25
          • 1970-01-01
          • 1970-01-01
          • 2020-09-26
          • 1970-01-01
          • 2017-11-17
          • 1970-01-01
          • 2019-03-27
          相关资源
          最近更新 更多