Python: json Datei lesen und Objekte plotten

Gast #5130998
Hallo zusammen,

ich bin neu mit python unterwegs und habe eigentlich eine recht simple 
Aufgabe vor mir (habe ich gedacht).

Ich habe ein json File mit verschiedenen Keys Obejekten und möchte diese 
plotten.
1
import numpy as np
2
import matplotlib.pyplot as plt

Ich erstelle mir ein def zum plotten
1
def chart_plot(x,y):
2
    plt.plot(x,y)
3
    plt.grid(True)
4
    plt.ylabel('wert')
5
    plt.xlabel('time')
6
    plt.show()

Ich lade also die json:
1
chart = json.loads(open('base.json').read())

Dann soll er die numpy arrays solange füllen, wie es die Anzahl der 
Zeitstempel (key date) vorgibt.
1
for i in range(0,len(chart['date'])):
2
        x = np.array(chart['date'])
3
        y = np.array(chart['wert'])
4
    chart_plot(x,y)

Leider kommt immer ein Fehler:
1
TypeError: list indices must be integers or slices, not str

Ich habe echt alles versucht.
Habe es sogar über pandas und dataframe versucht, mit dem gleichen 
Ergebnis/Fehler.

Kann mir jemand sagen, wo mein Fehler ist bzw kann mir ein einfaches Bsp 
zeigen, wie ich eine json auslese und zwei Objekte davon in einem 
x-y-Diagramm plotten kann?

Ich dachte die Aufgabe ist einfach, aber auch nach 2h komme ich nicht 
zum Ziel.

Vielen Dank!
Andi :)
Moderator #5131175
Zeig mal deine JSON-Datei.

Bei mir funktioniert dein Code mit folgendem Inhalt von base.json:

1
{
2
  "date": [ 1, 2, 4, 8 ],
3
  "wert": [ 1.1, 2.2, 3.3, 4.4 ]
4
}

Die Zeile

1
for i in range(0,len(chart['date'])):

kannst du dir sparen. Das Programm funktioniert zwar auch mit ihr,
befüllt die Array x und y aber unsinnigerweise mehrmals.

Die Zeilen

1
x = np.array(chart['date'])
2
y = np.array(chart['wert'])

befüllen jeweils das komplette Array, und mehr willst du wahrscheinlich
nicht.
Gast #5131205
Chart hat genau den Inhalt der json Datei.
Print(Chart) gibt in der Ausgabe das aus, was man auch in einem Editor 
sehen würde.

An anderer Stelle funktioniert der Zugriff auf die Objekte aber auf 
diese Art und Weise... Mhm...
Gast #5131220
Die json sieht bei mir etwas anders aus:
1
[{"date":12345,"wert":6789},{"date":23456,"wert":2763}]

Die Klammern sind also etwas anders... Aber das sollte dem Finden der 
Keys doch keinen Abbruch tun?

Vielen Dank!
Andi
#5131235
Andi schrieb:
> Die json sieht bei mir etwas anders aus:
>
1
> [{"date":12345,"wert":6789},{"date":23456,"wert":2763}]
2
>
>
> Die Klammern sind also etwas anders... Aber das sollte dem Finden der
> Keys doch keinen Abbruch tun?

Doch, natürlich. Was Du da hast, ist eine Liste von Dictionaries. Auf 
die Liste kannst Du nur mit Integer-Indices zugreifen. Was Du also 
machen willst, ist:
1
meineListe = [{"date":12345,"wert":6789},{"date":23456,"wert":2763}]
2
x = [e['date'] for e in meineListe]
3
y = [e['wert'] for e in meineListe]

oder etwas langsamer, dafür mehr Möglichkeiten die Daten "on the fly" zu 
manipulieren:
1
meineListe = [{"date":12345,"wert":6789},{"date":23456,"wert":2763}]
2
x, y = list(), list()
3
for e in meineListe:
4
  x.append(e['date'])
5
  y.append(e['wert'])

oder, wie vor:
1
meineListe = [{"date":12345,"wert":6789},{"date":23456,"wert":2763}]
2
x = map(lambda e: e['date'], d)
3
y = map(lambda e: e['wert'], d)
Moderator #5131350
Oder als Einzeiler ohne List-Comprehension und mit nur einem Lambda
(dieses zu eliminieren würde den Ausdruck stark in die Länge ziehen):
1
chart_plot(*zip(*map(lambda d:map(d.get,['date','wert']),json.load(open('base.json')))))
Gast #5131878
Vielen herzlichen Dank!

Sheeva P. schrieb:
> meineListe = [{"date":12345,"wert":6789},{"date":23456,"wert":2763}]
> x = [e['date'] for e in meineListe]
> y = [e['wert'] for e in meineListe]

Wie kann ich in diesen Plot eine einfache rote Linie plotten mit einem 
float Wert?
Offenbar sind x unx y nicht mit int/float in einem Plot vereinbar...

Vielen Dank!
Andi
#5132019
Andi schrieb:
> Wie kann ich in diesen Plot eine einfache rote Linie plotten mit einem
> float Wert?
> Offenbar sind x unx y nicht mit int/float in einem Plot vereinbar...

Aber ja doch:
1
from matplotlib import pyplot as plt
2
import dateutil.parser
3

4
# statt json.load()...
5
d = [{'date': '2017-01-01', 'wert': 5}, 
6
     {'date': '2017-02-01', 'wert': 4}, 
7
     {'date': '2017-03-01', 'wert': 5},
8
     {'date': '2017-04-01', 'wert': 6},
9
     {'date': '2017-05-01', 'wert': 6}]
10

11
x = [dateutil.parser.parse(e['date']) for e in d]
12
y1 = [e['wert'] for e in d]
13
y2 = len(y1) * [4.4]
14

15
plt.plot(x, y1)
16
plt.plot(x, y2, 'r')
17
plt.show()

Ach so, kleiner Hinweis am Rande: matplotlib ist eine leistungsfähige 
und IIRC an Matlab angelehnte Python-Library, und daher wahrscheinlich 
keine besonders gute Übung für den Einstieg ist. Auch wenn Du gerade 
Dein ganz konkretes Problem lösen möchtest, erscheint es mir 
zielführender, zuerst einmal die Grundzüge der Sprache zu erwerben: 
Datentypen wie Listen und Dictionaries, List- und Dict-Comprehensions, 
die Builtinfunktionen sowie vielleicht eine kleine Tour durch die 
Standardmodule. YMMV. ;-)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.