2017-10-21 109 views

Répondre

4

Regardons un exemple minimal, où nous créons des axes avec plt.subplots, voir aussi this question,

import matplotlib.pyplot as plt 

fig, axes = plt.subplots(ncols=2,nrows=3, sharex=True, sharey=True) 

for i, ax in enumerate(axes.flat): 
    ax.scatter([i//2+1, i],[i,i//3]) 

plt.show() 

Ici, axes est un tableau numpy d'axes,

print(type(axes)) 
> <type 'numpy.ndarray'> 
print(axes.shape) 
> (3L, 2L) 

axes.flat est pas fonction, c'est un attribut du numpy.ndarray: numpy.ndarray.flat

ndarray.flat Un itérateur 1-D sur l'ensemble.
Il s'agit d'une instance de numpy.flatiter, qui agit de la même manière que l'objet itérateur intégré de Python, mais qui n'en est pas une sous-classe.

Exemple:

import numpy as np 

a = np.array([[2,3], 
       [4,5], 
       [6,7]]) 

for i in a.flat: 
    print(i) 

qui imprimerait les numéros 2 3 4 5 6 7.

Être un interator sur le tableau, vous pouvez l'utiliser en boucle sur tous les axes de la matrice de 3x2 d'axes,

for i, ax in enumerate(axes.flat): 

Pour chaque itération, il rapporterait les prochains axes de ce tableau, de sorte que vous pouvez facilement tracer sur tous les axes dans une seule boucle.

Une alternative serait d'utiliser axes.flatten(), où flatten() est la méthode du tableau numpy. Au lieu d'un itérateur, il retourne une version aplatie du tableau:

for i, ax in enumerate(axes.flatten()): 

Il n'y a pas de différence vu de l'extérieur entre les deux. Cependant, un itérateur ne crée pas réellement un nouveau tableau et peut donc être légèrement plus rapide (bien que cela ne soit jamais visible dans le cas des objets d'axes matplotlib).

flat1 = [ax for ax in axes.flat] 
flat2 = axes.flatten() 
print(flat1 == flat2) 
> [ True True True True True True] 

Itère une version aplatie du tableau d'axes a l'avantage que vous économiserez une boucle, par rapport à l'approche naïve des itérer sur les lignes et les colonnes séparément,

for row in axes: 
    for ax in row: 
     ax.scatter(...)