Como resolver AttributeError: o objeto 'numpy.ndarray' não tem o atributo 'get_figure' ao plotar subtramas [duplicado]

Oct 03 2020

Estou tendo um problema quando tento executar uma célula de código. Estou tentando fazer um gráfico de dispersão para cada uma das variáveis ​​em meu dataframe, mas estou encontrando um erro sobre o qual não tenho muita certeza. Você pode ajudar?

Meu 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')

Erro retornado: AttributeError: 'numpy.ndarray' objeto não tem atributo 'get_figure'

Respostas

1 TrentonMcKinney Oct 03 2020 at 23:18
  • fig, axes = plt.subplots(nrows=3, ncols=7, figsize=(12,10))cria 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)
  • Ao compactar com zip(df[df.columns], axes), você obtém algo como o seguinte:
    • Esta é a origem do erro; como você pode ver, axpelo loop, é um array, não um 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))]
  • O que você deseja é compactar uma coluna em uma subtrama, o que pode ser feito descompactando todas as subparcelas dos eixos, com uma compreensão de lista, ou usando axes.ravel()e compactando-as com os nomes das colunas.
    • numpy.ravel retorna uma matriz achatada.
  • Use df.columns, não df[df.columns], para obter os nomes das colunas.
# 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:>)]

Exemplo

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