Cómo resolver AttributeError: el objeto 'numpy.ndarray' no tiene atributo 'get_figure' al trazar subtramas [duplicado]

Oct 03 2020

Me encuentro con un problema cuando intento ejecutar una celda de código. Estoy intentando hacer un diagrama de dispersión para cada una de las variables en mi marco de datos, pero encuentro un error del que no estoy muy seguro. ¿Puede usted ayudar?

Mi código:

fig, axes = plt.subplots(nrows=3, ncols=7, figsize=(12,10))
for xcol, ax in zip(df[df.columns], axes):
    df.plot(kind='scatter', x=xcol, y='price', ax=ax, alpha=0.5, color='r')

Error devuelto: AttributeError: el objeto 'numpy.ndarray' no tiene el atributo 'get_figure'

Respuestas

1 TrentonMcKinney Oct 03 2020 at 23:18
  • fig, axes = plt.subplots(nrows=3, ncols=7, figsize=(12,10))crea 3 grupos de 7 AxesSubplotobjetos
array([[<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>],
       [<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>],
       [<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>]], dtype=object)
  • Al comprimir con zip(df[df.columns], axes), obtienes algo como lo siguiente:
    • Estas son las fuentes del error; como puede ver, axen el bucle, es un array, no un AxesSubplot.
[('col1', array([<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>], dtype=object)),
 ('col2', array([<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>], dtype=object)),
 ('col3', array([<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>], dtype=object))]
  • Lo que quiere es comprimir una columna en una subtrama, lo que se puede hacer desempaquetando todas las subtramas de los ejes, con una lista de comprensión, o usando axes.ravel()y luego comprimiéndolas en los nombres de las columnas.
    • numpy.ravel devuelve una matriz aplanada.
  • Use df.columns, no df[df.columns], para obtener los nombres de las columnas.
# the list comprehension unpacks all the axes
zip(df.columns, [x for v in axes for x in v])

# which results in one column name per subplot
[('col1', <AxesSubplot:>),
 ('col2', <AxesSubplot:>),
 ('col3', <AxesSubplot:>),
 ('col4', <AxesSubplot:>),
 ('col5', <AxesSubplot:>),
 ('col6', <AxesSubplot:>),
 ('col7', <AxesSubplot:>),
 ('col8', <AxesSubplot:>),
 ('col9', <AxesSubplot:>),
 ('col10', <AxesSubplot:>),
 ('col11', <AxesSubplot:>),
 ('col12', <AxesSubplot:>),
 ('col13', <AxesSubplot:>),
 ('col14', <AxesSubplot:>),
 ('col15', <AxesSubplot:>),
 ('col16', <AxesSubplot:>),
 ('col17', <AxesSubplot:>),
 ('col18', <AxesSubplot:>),
 ('col19', <AxesSubplot:>),
 ('col20', <AxesSubplot:>),
 ('col21', <AxesSubplot:>)]

Ejemplo

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# load sample data
df = sns.load_dataset('car_crashes')

# setup figure
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(12, 10))

# iterate and plot subplots
for xcol, ax in zip(df.columns[1:-1], [x for v in axes for x in v]):
    df.plot.scatter(x=xcol, y='speeding', ax=ax, alpha=0.5, color='r')