web-dev-qa-db-fra.com

Erreur lors de l'importation matplotlib.pyplot (sur Anaconda3 pour PC Windows 10 Home 64 bits)

J'ai récemment installé "Anaconda3 pour Windows v2.4.0" sur ma machine Windows 10 Home (64 bits).

(J'ai téléchargé le programme d'installation graphique Windows 64 bits "Anaconda3-2.4.0-Windows-x86_64.exe" (392 Mo) à partir de https://www.continuum.io/downloads .)

Dans une fenêtre d'invite de commandes, j'ai fait le conda "Test Drive", y compris "conda update conda", etc. À la fin, je vois ce qui suit:

C:\Users\Anshul\Downloads\Python>conda update conda
Fetching package metadata: ....
# All requested packages already installed.
# packages in environment at C:\Anaconda3:
#
conda                     3.18.6                   py35_0    defaults

C:\Users\Anshul\Downloads\Python>conda list matplotlib
# packages in environment at C:\Anaconda3:
#
matplotlib                1.5.0               np110py35_0    defaults

L'installation semble avoir réussi - par exemple:

C:\Users\Anshul\Downloads\Python>python
Python 3.5.0 |Anaconda 2.4.0 (64-bit)| (default, Nov  7 2015, 13:15:24) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello World")
Hello World
>>> import os
>>> os.getcwd()
'C:\\Users\\Anshul\\Downloads\\Python'
>>> import matplotlib as mpl
>>> print(mpl.__version__)
1.5.0
>>> 

Notez que matplotlib a été importé bien ci-dessus. Cependant, je reçois un message d'erreur lorsque j'essaie d'importer "matplotlib.pyplot" comme indiqué ci-dessous:

>>> import matplotlib.pyplot as pp
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 1412, in <module>
    fontManager = pickle_load(_fmcache)
  File "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 963, in pickle_load
    with open(filename, 'rb') as fh:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Anshul\\.matplotlib\\fontList.py3k.cache'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda3\lib\site-packages\matplotlib\pyplot.py", line 29, in <module>
    import matplotlib.colorbar
  File "C:\Anaconda3\lib\site-packages\matplotlib\colorbar.py", line 34, in <module>
    import matplotlib.collections as collections
  File "C:\Anaconda3\lib\site-packages\matplotlib\collections.py", line 27, in <module>
    import matplotlib.backend_bases as backend_bases
  File "C:\Anaconda3\lib\site-packages\matplotlib\backend_bases.py", line 62, in <module>
    import matplotlib.textpath as textpath
  File "C:\Anaconda3\lib\site-packages\matplotlib\textpath.py", line 15, in <module>
    import matplotlib.font_manager as font_manager
  File "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 1420, in <module>
    _rebuild()
  File "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 1405, in _rebuild
    fontManager = FontManager()
  File "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 1043, in __init__
    self.ttffiles = findSystemFonts(paths) + findSystemFonts()
  File "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 312, in findSystemFonts
    for f in win32InstalledFonts(fontdir):
  File "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 231, in win32InstalledFonts
    direc = os.path.abspath(direc).lower()
  File "C:\Anaconda3\lib\ntpath.py", line 535, in abspath
    path = _getfullpathname(path)
ValueError: _getfullpathname: embedded null character
>>>

J'ai ouvert "C:\Anaconda3\lib\site-packages\matplotlib\font_manager.py" dans un éditeur de texte et j'ai essayé de rechercher la source de l'erreur. Je pense que c'est là que les choses tournent mal:

>>> mpl.get_cachedir()
'C:\\Users\\Anshul\\.matplotlib'
>>> mpl.get_configdir()
'C:\\Users\\Anshul\\.matplotlib'
>>>

Dans l'Explorateur Windows, je vois que le dossier "C:\Users\Anshul.matplotlib" est vide, d'où le FileNotFoundError pour le fichier "fontList.py3k.cache" (que je ne vois nulle part dans le Répertoire "C:\Anaconda3" soit). Cela semble être un problème avec l'installateur (je pense), mais je ne sais pas comment le résoudre. J'apprécierais toute aide ou conseils.

(BTW, j'ai déjà essayé de googler ce problème. Celui qui s'est approché le plus a été signalé en 2013: échec de l'importation de matplotlib.pyplot # 232 . Il s'agissait d'une installation WinPython-64bit-3.3.2.2 sur une machine Windows 7 64 bits. Le fil de discussion a été fermé avec le commentaire: "Fermeture. Déjà corrigé dans le maître.", mais il semble que le problème a refait surface. J'espère qu'il existe une solution simple ou une solution de contournement.)

Merci,
Anshul

18
Anshul Agrawal

C'est un bogue en python, pas matplotlib.

Le problème est que winreg.EnumValue Ne coupe pas les valeurs de chaîne à leur longueur correctement pour une raison quelconque, et les chaînes incluront des caractères nuls que os.path.abspath N'est pas en mesure de traiter.

L'entrée de registre où cela se produit est à SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts. Bien que ce ne soit pas la faute de matplotlib, nous pouvons toujours le corriger temporairement afin qu'il termine la chaîne à '\0'. Dans font_manager.py, Ligne de patch 310 dans la fonction win32InstalledFonts() pour:

key, direc, any = winreg.EnumValue( local, j)
if not is_string_like(direc):
    continue
if not os.path.dirname(direc):
    direc = os.path.join(directory, direc)
direc = direc.split('\0', 1)[0]
21
simonzack

J'utilise Python 3.5.2. Lorsque j'ai essayé la solution @simonzack, j'ai toujours une erreur. J'ai limité l'exception au fichier <python>/Lib/ntpath.py. Recherchez la définition de la fonction abspath() autour de la ligne 530.

J'ai ajouté la solution de @ simonzack à un gestionnaire d'exceptions ValueError. Insérez le code suivant après la ligne 537:

    530:    def abspath(path):
    531:    """Return the absolute version of a path."""

    533:    if path: # Empty path must return current working directory.
    534:        try:
    535:            path = _getfullpathname(path)
    536:        except OSError:
    537:            pass # Bad path - return unchanged.
    NEW:        except ValueError:
    NEW:            path = path.split('\0', 1)[0]
    NEW:            path = _getfullpathname(path)
    538:    Elif isinstance(path, bytes):
    539:        path = os.getcwdb()
    540:    else:
    541:        path = os.getcwd()
    542:    return normpath(path)

Cela a corrigé l'erreur pour moi.

Pour un petit historique sur la cause de ce problème, jetez un œil à: Python Issue 25778 . C'est un peu long mais la conclusion finale est que le correctif n'est pas entré dans 2.7.14, 3.5.3 ou 3.6.0. Il semble donc que ce hack sera notre seule solution pour les anciennes versions de Python.

0
Quantium