web-dev-qa-db-fra.com

TypeError: Dimensions non valides pour les données d'image lors du traçage d'un tableau avec imshow ()

Pour le code suivant

# Numerical operation
SN_map_final = (new_SN_map - mean_SN) / sigma_SN  

# Plot figure
fig12 = plt.figure(12)
fig_SN_final = plt.imshow(SN_map_final, interpolation='nearest')
plt.colorbar()

fig12 = plt.savefig(outname12)

avec new_SN_map étant un tableau 1D et mean_SN et sigma_SN étant des constantes, j'obtiens l'erreur suivante.

Traceback (most recent call last):
  File "c:\Users\Valentin\Desktop\Stage M2\density_map_simple.py", line 546, in <module>
    fig_SN_final = plt.imshow(SN_map_final, interpolation='nearest')
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\pyplot.py", line 3022, in imshow
    **kwargs)
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\__init__.py", line 1812, in inner
    return func(ax, *args, **kwargs)
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\axes\_axes.py", line 4947, in imshow
    im.set_data(X)
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\image.py", line 453, in set_data
    raise TypeError("Invalid dimensions for image data")
TypeError: Invalid dimensions for image data

Quelle est la source de cette erreur? Je pensais que mes opérations numériques étaient autorisées.

24
Essex

Il y a une question (un peu) connexe sur StackOverflow:

Ici, le problème était qu'un tableau de forme (nx, ny, 1) est toujours considéré comme un tableau 3D et doit être squeezed ou découpé en un tableau 2D.

Plus généralement, le motif de l'exception

TypeError: Dimensions non valides pour les données d'image

est montré ici: matplotlib.pyplot.imshow() nécessite un tableau 2D, ou un tableau 3D avec la troisième dimension de forme 3 ou 4!

Vous pouvez facilement vérifier cela avec (ces vérifications sont effectuées par imshow, cette fonction est uniquement destinée à donner un message plus spécifique au cas où ce ne serait pas une entrée valide):

from __future__ import print_function
import numpy as np

def valid_imshow_data(data):
    data = np.asarray(data)
    if data.ndim == 2:
        return True
    Elif data.ndim == 3:
        if 3 <= data.shape[2] <= 4:
            return True
        else:
            print('The "data" has 3 dimensions but the last dimension '
                  'must have a length of 3 (RGB) or 4 (RGBA), not "{}".'
                  ''.format(data.shape[2]))
            return False
    else:
        print('To visualize an image the data must be 2 dimensional or '
              '3 dimensional, not "{}".'
              ''.format(data.ndim))
        return False

Dans ton cas:

>>> new_SN_map = np.array([1,2,3])
>>> valid_imshow_data(new_SN_map)
To visualize an image the data must be 2 dimensional or 3 dimensional, not "1".
False

Le np.asarray Correspond à ce qui est fait en interne par matplotlib.pyplot.imshow, Il est donc généralement préférable de le faire aussi. Si vous avez un tableau numpy, il est obsolète mais sinon (par exemple, un list), il est nécessaire.


Dans votre cas spécifique, vous avez un tableau 1D, vous devez donc ajouter une dimension avec np.expand_dims()

import matplotlib.pyplot as plt
a = np.array([1,2,3,4,5])
a = np.expand_dims(a, axis=0)  # or axis=1
plt.imshow(a)
plt.show()

enter image description here

ou utilisez simplement quelque chose qui accepte les tableaux 1D comme plot:

a = np.array([1,2,3,4,5])
plt.plot(a)
plt.show()

enter image description here

40
MSeifert