Installation von matplotlib schlägt fehl

Probleme bei der Installation?
Antworten
Tuetenflieger
User
Beiträge: 5
Registriert: Dienstag 1. September 2020, 21:24

Hallo,
ich habe als Python-Anfänger ein Problem mit der Installation von python3-matplotlib.
IDLE 3.7.5 mit Python 3.7.5 wurde normal über die Paketverwaltung in Linux Mint 19.3 Cinnamin installiert.
python3-matplotlib wurde auch über die normale Paketverwaltung von Linux Mint installiert.
Ich bekomme bei dem Basisskript

Code: Alles auswählen

import matplotlib.pyplot
folgende Fehlermeldung:

Traceback (most recent call last):
File "/home/niels/test3.py", line 1, in <module>
import matplotlib.pyplot
File "/usr/lib/python3/dist-packages/matplotlib/pyplot.py", line 32, in <module>
import matplotlib.colorbar
File "/usr/lib/python3/dist-packages/matplotlib/colorbar.py", line 32, in <module>
import matplotlib.artist as martist
File "/usr/lib/python3/dist-packages/matplotlib/artist.py", line 16, in <module>
from .path import Path
File "/usr/lib/python3/dist-packages/matplotlib/path.py", line 25, in <module>
from . import _path, rcParams
ImportError: cannot import name '_path' from 'matplotlib' (/usr/lib/python3/dist-packages/matplotlib/__init__.py)

Könnt Ihr mir weiterhelfen ?

Danke!

Tütenflieger
tonikae
User
Beiträge: 90
Registriert: Sonntag 23. Februar 2020, 10:27

Du solltest den Namen der Bibliothek angeben
(ein Punkt reicht nicht), wenn du einzelne Module
aus einer Bibliothek importieren willst
Hier so:

import matplotlib.pyplot
from matplotlib import _path, rcParams

Eine Liste der einzelnen Module in einer Bibliothek
kannst du mit: print(dir(<Bibliotheksnamen>))
Hier: print(dir(matplotlib)) ansehen.
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tonikae: Erstens reicht ein Punkt wenn man relativ aus dem gleichen Package importieren möchte in dem das importierende Modul liegt, und zweitens ist dieser Importcode nicht von Tuetenflieger, sondern steht im `matplotlib.path`-Modul.

Das mit dem `dir()` funktioniert nicht zuverlässig, denn dafür müssten die Module in dem Package bereits importiert worden sein. Das kann der Fall sein, muss es aber nicht.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

_path ist eine binäre Shared Library. Die muß für jede Python-Version neu compiliert werden.
Du wirst also eine matplotlib-Installation verwenden, die nicht zu Deinem aktuell gestarteten Python passt.

Welches Python startest Du also?
Was sagen sys.executable und sys.version?
tonikae
User
Beiträge: 90
Registriert: Sonntag 23. Februar 2020, 10:27

__blackjack__ hat geschrieben: Dienstag 8. September 2020, 11:57 @tonikae: Erstens reicht ein Punkt wenn man relativ aus dem gleichen Package importieren möchte in dem das importierende Modul liegt, und zweitens ist dieser Importcode nicht von Tuetenflieger, sondern steht im `matplotlib.path`-Modul.

Das mit dem `dir()` funktioniert nicht zuverlässig, denn dafür müssten die Module in dem Package bereits importiert worden sein. Das kann der Fall sein, muss es aber nicht.
Äh...seid ihr hier eigentlich alle so blöd...oder tut ihr nur so ?
Oder was soll diese strunzdumme Anmache hier ?

Erstes: Wenn ein Punkt gereicht hätte, hät er keine Fehlermeldung gekriegt
Zweitens: kannst du offenbar nicht zwischen Lib und Mod unterschieden
Drittens: funktioniert das mit dem "Dir" sogar auf Online-Notebooks https://drive.google.com/file/d/1y1n0QN ... VG27H/view
Benutzeravatar
Damaskus
Administrator
Beiträge: 995
Registriert: Sonntag 6. März 2005, 20:08
Wohnort: Schwabenländle

tonikae hat geschrieben: Dienstag 8. September 2020, 15:16 Äh...seid ihr hier eigentlich alle so blöd...oder tut ihr nur so ?
Oder was soll diese strunzdumme Anmache hier ?
@tonikae:
Beim nächsten Mal wenn du die Netiquette mit solchen Äußerungen verlässt, dann erfolgt ein umgehender Bann vom Forum.
Bitte halte dich an die die klassischen Regeln von respektvollem und höflichem Umgang hier im Forum.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

tonikae hat geschrieben: Dienstag 8. September 2020, 15:16 Äh...seid ihr hier eigentlich alle so blöd...oder tut ihr nur so ?
Oder was soll diese strunzdumme Anmache hier ?

Erstes: Wenn ein Punkt gereicht hätte, hät er keine Fehlermeldung gekriegt
Zweitens: kannst du offenbar nicht zwischen Lib und Mod unterschieden
Drittens: funktioniert das mit dem "Dir" sogar auf Online-Notebooks https://drive.google.com/file/d/1y1n0QN ... VG27H/view
Fuer jemanden, der dermassen rauskloppt, hast du erstaunlich wenig Ahnung. Selbstverstaendliche werden Unterpakete oder Module in einem Paket (package und module im englischen, den Begriff "Lib" benutzt man hier nicht) natuerlich NICHT automatisch importiert in den Namensraum des Paketes darunter. Wie man leicht sieht:

Code: Alles auswählen

import sys
import pathlib
import tempfile


with tempfile.TemporaryDirectory() as tdir:
    tdir = pathlib.Path(tdir)
    package = tdir / "package"
    package.mkdir()
    (package / "__init__.py").touch()
    for name in ("foo", "bar"):
        module = package / f"{name}.py"
        with module.open("w") as outf:
            outf.write(f"""print("{name}")""")
    sys.path.append(str(tdir))
    import package
    print(dir(package))
    import package.foo
    import package.bar
    print(dir(package))
Leuten, die dermassen offensichtlich mehr Erfahrung und tiefergehende Kenntnisse haben als du, so bloede zu kommen - stramme Leistung!
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tonikae: Ad Erstens: Ein Punkt reicht für einen relativen Import. Siehe den Abschnitt Package Relative Imports in der Sprachreferenz in der Python-Dokumentation.

Für eine praktische Anwendung kann man sich das `matplotlib.path`-Modul ansehen, wo ja genau diese Zeile drinsteht: ``from . import _path, rcParams``. Wenn das nicht funktionieren würde, gäbe es das von Dir verlinkte Bildschirmfoto nicht, denn dort funktioniert der Import von `matplotlib.pyplot` ja, der unter anderem auch den Import von `matplotlib.path` zur Folge hat, und damit die Ausführung dieser Zeile.

Ad Zweitens: Da bin ich mir in der Tat jetzt unsicher was Du meinst, denn zwischen einer Lib(rary) und einem Mod(ul) muss es keinen Unterschied geben. Bezogen auf erstens meinst Du vielleicht den Unterschied zwischen einem Package und einem Modul!? Den kenne ich. Ein Package kann weitere Packages und Module enthalten, selbst aber auch wie ein Modul importiert werden. Und in Modulen (und damit auch Packages) kann man mit einem "." beim ``from … import …`` relativ zum aktuellen Package importieren. Siehe erstens.

Library ist ein Oberbegriff der sowohl ein oder mehere Packages als auch ein Modul meinen kann. Beispiel für letzteres, um zu zeigen das Library nicht einfach ein Synonym für Package ist, wäre das `contextlib`-Modul aus der Standardbibliothek. Und Standardbibliothek also „standard library“ umfasst mehrere Packages (und Module).

Ad Drittens: Wenn man sich mit `dir()` die Module eines Packages auflisten lassen könnte, also so ganz grundsätzlich ohne da nocht etwas für tun zu müssen, dann müsste man zum Beispiel `tkinter` importieren können und da mit `dir()` in der Liste beispielsweise "ttk" finden können. Dem ist aber nicht so. Das muss man erst importieren, bevor es ein Attribut vom `tkinter`-Modul ist:

Code: Alles auswählen

In [255]: import tkinter                                                        

In [256]: "ttk" in dir(tkinter)                                                 
Out[256]: False

In [257]: import tkinter.ttk                                                    

In [258]: "ttk" in dir(tkinter)                                                 
Out[258]: True
`matplotlib.pyplot` ist dabei noch nicht einmal ein Package, also kann man dort auch nur die Module als Attribute finden, die von diesem Modul selbst importiert werden. Und nicht alle Module von der `matplotlib`-Bibliothek.

Von den 251 Attributen deren Namen man mit `dir()` vom `matplotlib.pyplot`-Modul abfragen kann, sind auch nur 16 Module. Und von diesen 16 Modulen sind wiederum nur die Hälfte Module aus der Matplotlib-Bibliothek. Da ist noch `numpy` und sieben Module aus der Standardbibliothek. Wobei man das den Attributnamen die `dir()` liefert, nicht so leicht ansieht wo sie herkommen:

Code: Alles auswählen

['_backend_mod',
 '_pylab_helpers',
 'cm',
 'docstring',
 'importlib',
 'inspect',
 'logging',
 'matplotlib',
 'mlab',
 'np',
 'rcsetup',
 're',
 'style',
 'sys',
 'time',
 'warnings']
Da muss man sich schon die Objekte hinter den Attributnamen hernehmen und deren qualifizierten Namen anschauen:

Code: Alles auswählen

['importlib',
 'inspect',
 'logging',
 'matplotlib',
 'matplotlib._pylab_helpers',
 'matplotlib.backends.backend_tkagg',
 'matplotlib.cm',
 'matplotlib.docstring',
 'matplotlib.mlab',
 'matplotlib.rcsetup',
 'matplotlib.style',
 'numpy',
 're',
 'sys',
 'time',
 'warnings']
Das leistet aber `dir()` nicht ohne zusätzlichen Code zu schreiben. Und wie gesagt, diese 8 Namen sind sehr wenige unter 251 Namen insgesamt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Tuetenflieger
User
Beiträge: 5
Registriert: Dienstag 1. September 2020, 21:24

Hallo,
vielen Dank, daß es doch noch Antworten gibt, aber ich wollte hier als fast-DAU keine Grabenkämpfe initiieren, vor allem keine, die ich nicht verstehe...
(Zwischenzeitlich bin ich zwar als Workaround auf Anaconda unter Win8.1 ausgewichen, dort funktionierte dann der Import), aber ich habe eigentlich den Anspruch mich MS zu entwöhnen und bis zum Januar 2023 endgültig zu migrieren)
Ich habe das jetzt noch mal unter Linux Mint getestet:

@Sirius3:
sys.executable gibt '/usr/bin/python3.7' aus, und
sys.version: '3.7.5 (default, Nov 7 2019, 10:50:52) \n[GCC 8.3.0]'

@tonikae
ein import matplotlib geht ohne Fehlermeldung, ein
ein import matplotlib.pyplot gibt die bekannte Fehlermeldung, und ein
import matplotlib
from matplotlib import _path, rcParams
ein SyntaxError: multiple statements found while compiling a single statement

Wenn ich ein print(dir(matplotlib)) mache, gibt es die Fehlermeldung SyntaxError: unexpected indent

Gruß,
Tütenflieger
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

Du verwendest also das System-Python und hast ein System-Matplotlib installiert. Das ist seltsam. Hast Du noch andere Pythons installiert?
Wie heißt die Datei (/usr/lib/python3/dist-packages/matplotlib/_path* genau?

Auch bei einem einfachen print muß der Code korrekt eingerückt sein. Einrückung ist in Python wichtig.
Tuetenflieger
User
Beiträge: 5
Registriert: Dienstag 1. September 2020, 21:24

Hallo,
@Sirius3: Es ist nicht trivial für mich, unter Linux festzustellen welche anderen Versionen noch installiert sind. Ich finde unter /usr/bin/ die 3-5 MB großen Programmdateien: python2.7, python3.6, python3.6m, python3.7 und python3.7m
Unter der Linux Mint Synaptic-Paketverwaltung wird aufgeführt: 2.7.15, 2.7.17, 3.6.7, 3.6.9 und 3.7.5

Unter /usr/lib gibt es die Unterverzeichnisse python2.7, python3, python3.6, python3.7 und python3.8

Unter /usr/lib/python3/dist-packages/matplotlib gibt es die Datei _path-cpython-36m-x86_64-linux-gnu.so

Ich habe jetzt nochmal in IDLE die Befehle

Code: Alles auswählen

import matplotlib
print(dir(matplotlib))
laufen lassen, und komme nun zu der Ausgabe

Code: Alles auswählen

['MutableMapping', 'RcParams', 'URL_REGEX', 'Verbose', '_DATA_DOC_APPENDIX', '__bibtex__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '__version__numpy__', '__warningregistry__', '_all_deprecated', '_backports', '_color_data', '_create_tmp_config_dir', '_decode_filesystem_path', '_deprecated_ignore_map', '_deprecated_map', '_deprecated_set', '_error_details_fmt', '_get_cachedir', '_get_config_or_cache_dir', '_get_configdir', '_get_data_path', '_get_data_path_cached', '_get_home', '_get_xdg_cache_dir', '_get_xdg_config_dir', '_init_tests', '_is_writable_dir', '_obsolete_set', '_open_file_or_url', '_preprocess_data', '_python27', '_python34', '_rc_params_in_file', '_replacer', '_url_lines', '_use_error_msg', '_version', 'absolute_import', 'cbook', 'checkdep_dvipng', 'checkdep_ghostscript', 'checkdep_inkscape', 'checkdep_pdftops', 'checkdep_ps_distiller', 'checkdep_tex', 'checkdep_usetex', 'checkdep_xmllint', 'colors', 'compare_versions', 'compat', 'contextlib', 'cycler', 'dateutil', 'dedent', 'defaultParams', 'default_test_modules', 'distutils', 'division', 'fontconfig_pattern', 'functools', 'get_backend', 'get_cachedir', 'get_configdir', 'get_data_path', 'get_home', 'get_label', 'get_py2exe_datafiles', 'inspect', 'interactive', 'io', 'is_interactive', 'is_url', 'itertools', 'locale', 'matplotlib_fname', 'mplDeprecation', 'numpy', 'os', 'print_function', 'pyparsing', 'rc', 'rcParams', 'rcParamsDefault', 'rcParamsOrig', 'rc_context', 'rc_file', 'rc_file_defaults', 'rc_params', 'rc_params_from_file', 'rcdefaults', 'rcsetup', 're', 'reload', 'sanitize_sequence', 'six', 'subprocess', 'sys', 'tempfile', 'test', 'tk_window_focus', 'unicode_literals', 'urlopen', 'use', 'validate_backend', 'verbose', 'warnings']
Ein pyplot kann ich da nicht finden.

Gruß,
Tütenflieger
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

Das mit dem `dir` hat __blackjack__ ja ausführlich beschrieben.
Die _path-Datei sagt, dass Du matplotlib für python3.6 installiert hast. Wenn Du diese Python-Version verwendest, sollte es einwandfrei funktionieren.
Tuetenflieger
User
Beiträge: 5
Registriert: Dienstag 1. September 2020, 21:24

@Sirius3: Ich habe keine Ahnung, warum ich so viele verschiedene Python-Versionen auf dem Rechner habe. Daß eine 2.7 drauf ist, ist mir wg. Kompatibilität einiger Programme klar, aber warum es mehrere Python3 Versionen gibt, verstehe ich nicht. Ich habe sie nicht bewußt installiert.
Um IDLE mit Python 3.6 statt 3.7 zu starten, hatte ich versucht die Datei von Python 3.7 "/usr/bin/idle-python3.7" mit einem zu Python3.6 geänderten Eintrag zu modifizieren:

Code: Alles auswählen

#! /usr/bin/python3.6

from idlelib.pyshell import main
if __name__ == '__main__':
    main()
Das schlug leider fehl mit der Meldung

Code: Alles auswählen

Traceback (most recent call last):
  File "/usr/bin/idle-python3.6", line 3, in <module>
    from idlelib.pyshell import main
ModuleNotFoundError: No module named 'idlelib'
Habt Ihr einen DAU-festen Hinweis für mich ?
Kann ich einfach über die Systemverwaltung Python3.7 deinstallieren, und hoffen, daß dann IDLE unter Python3.6 läuft ?

Gruß,
Tütenflieger
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Tuetenflieger: Wenn Du etwas deinstallierst wird nicht auf magische Weise etwas auf dem Rechner erscheinen was vorher nicht da war. Du musst IDLE für Python 3.6 installieren. Vorher solltest Du ``/usr/bin/idle-python3.6`` wieder löschen, denn genau *das* muss ja aus irgendeinem Paket kommen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Tuetenflieger
User
Beiträge: 5
Registriert: Dienstag 1. September 2020, 21:24

Hallo,
nach Deinstallation von IDLE3.7 und Installation von IDLE3.6 funktioniert nun der Import von matplotlib.pyplot. Danke für Eure Hilfe!
Ein print(dir(matplotlib)) listet nun auch pyplot auf.

@Sirius3: Ich war bisher davon ausgegangen, daß IDLE eigentlich "nur" eine IDE ist, die auf die ansonsten installierte Pythonversion aufgesetzt wird.

Ein echter Funktionstest steht noch aus, je nach Wetter kommt das am Wochenende dran...

Gruß,
Tütenflieger
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Tuetenflieger: IDLE 3.7 hätte man nicht deinstallieren müssen.

IDLE ist Bestandteil der Standardinstallation von Python, darum gibt es für jede Python-Version eine dazugehörige IDLE-Version.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten