Sehr geehrter Damen und Herren,
ich habe leider ein kleines Problem.
Undzwar besteht meine Aufgabe dadrin, ein Phyton programm zu erstellen, dass die aktuellen Temperaturen von einer seite Downloadet und dies als Grafik wieder gibt.
Was ich bisher gemacht habe :
-------------------------------------------------------------------------------------------------------------------------------
#Temperatur Csv Download
from urllib.request import urlopen
url= ("https://www.lanuv.nrw.de/fileadmin/lanu ... T_AM1H.csv")
Dateiname = "Temperatur.csv"
with open (Dateiname, "wb") as datei:
datei.write(urlopen(url).read())
#Csv datei und matplotlib einbinden
import csv
import matplotlib.pyplot as plt
#CSV Datei Öffnen und in Phyton wiedergeben
with open("Temperatur.csv", encoding="ansi") as datei:
for zeile in csv.DictReader(datei, delimiter=";"):
print(zeile)
-------------------------------------------------------------------------------------------------------------------------------
Nun weiß ich leider nicht mehr weiter, wie ich diese Csv datei so umwandeln kann, das ich auf der X achse das Datum und auf der Y achse die Temperatur angezeigt bekomme.
Außerdem ist dies für 360 tage ... also wird der Graf unübersichtlich, daher wollte ich auch es so programmieren, das ich eingeben muss, das ich es nur für die ersten 7 tage Z.b den graf haben möchte....
Ich entschuldige mich direkt auch für diese fragen...
Mit freundlichen Grüßen.
Eren
Csv datei in Python als Grafik darstellen
- DeaD_EyE
- User
- Beiträge: 1240
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Mit pandas wäre das wahrscheinlich recht einfach.
Bei dem CSV-Modul muss man viel "zu Fuß" machen.
Daten können Fehler enthalten und die sind abzufangen.
Eine Eigenart, die mir aufgefallen ist, dass die offensichtlich auch die Uhrzeit 24:00 verwenden.
Das kann man nicht direkt mit datetime parsen.
Bei dem CSV-Modul muss man viel "zu Fuß" machen.
Daten können Fehler enthalten und die sind abzufangen.
Eine Eigenart, die mir aufgefallen ist, dass die offensichtlich auch die Uhrzeit 24:00 verwenden.
Das kann man nicht direkt mit datetime parsen.
Code: Alles auswählen
import csv
from datetime import datetime as dt
from datetime import timedelta as td
from urllib.request import urlopen
import matplotlib.pyplot as plt
url= "https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/T_AM1H.csv"
dateiname = "Temperatur.csv"
with open (dateiname, "wb") as datei:
req = urlopen(url)
# nicht alles aufeinmal laden
while True:
chunk = req.read(64 * 1024)
if not chunk:
# keine Daten mehr, Datei zuende.
break
# Schreibe den block
datei.write(chunk)
field = "BONN T AM1H [°C]"
dt_format = '%d.%m.%Y %H:%M'
with open("Temperatur.csv") as datei:
next(datei)
# datei ist ein Iterator
# Im Header steht ein Kommentar, der zuerst verworfen werden muss
# next(datei) gibt die aktuelle Zeile aus, die hier aber nicht verwnedet wird
dict_reader = csv.DictReader(datei, delimiter=";")
# der DictReader bekommt als erstes Argument das Dateiobjekt
# dieser liest dann die erste Zeile mit den Feldnamen ein.
# Da der Kommentar bereits übersprungen ist, funktioniert das
dates = []
values = []
for row in dict_reader:
value = row[field].replace(",", ".")
if not value:
# wenn kein Wert vorhanden ist,
# dann überspringen
continue
datum = row["Datum"]
zeit = row["Zeit"]
# offensichtlich kommt auch 24 Uhr in den Datensätzen vor
# das wäre dann schon der nächste Tag
# 24:00 lässt sich aber nicht parsen
# also setze ich das auf 00:00 und
# füge einen Tag hinzu.
if '24:00' == zeit:
zeit = '00:00'
next_day = True
else:
next_day = False
zeitstempel = datum + " " + zeit
# Hier tritt ein Fehler auf, wenn die Zeitangabe
# ungültig ist
# ggf. mit try... except abfangen und überspringen
zeitstempel = dt.strptime(zeitstempel, dt_format)
# nächster Tag
if next_day:
zeitstempel += td(days=1)
# Deutsch > Englisch
# float("1,5") geht z.b. nicht
# deswegen , durch . ersetzen
# Wert auslesen und Komma durch Punkt ersetzen
# Wert in float umwandeln
# Bei der Umwandlung kann es zu einem ValueError
# kommen, sofern der string nicht in einen float
# umgewandelt werden kann
# auch hier, kann man mit try und except den Fehler
# abfangen und entsprechend reagieren.
value = float(value)
# wert zur Liste hinzufügen
values.append(value)
dates.append(zeitstempel)
plt.plot_date(dates, values, '-')
plt.show()
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Hallo:)
Erstmals danke für die schnelle antwort auf mein beitrag
Sie meinten es wäre mit pandas alles leichter?
Wie meinen sie das?
Ich brauche z. B für Bonn die Temperaturen und dies soll Matplotlip dann für die gewählte Tage ( das kann der User am Anfang aussuchen wie viel Tage der graf angezeigt werden soll)
Irgendwie kriege Ich das nicht hin.
Ich hoffe sie können mir mit pandas helfen.
Grüße
Erstmals danke für die schnelle antwort auf mein beitrag

Sie meinten es wäre mit pandas alles leichter?
Wie meinen sie das?
Ich brauche z. B für Bonn die Temperaturen und dies soll Matplotlip dann für die gewählte Tage ( das kann der User am Anfang aussuchen wie viel Tage der graf angezeigt werden soll)
Irgendwie kriege Ich das nicht hin.
Ich hoffe sie können mir mit pandas helfen.
Grüße

- DeaD_EyE
- User
- Beiträge: 1240
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Nach dem 10 mal datetime.datetime.now, datetime.datetime.fromisoformat, datetime.timedelta gehen mir die Wiederholungen auf den Sack.Sirius3 hat geschrieben: Montag 20. Januar 2020, 16:21 @DeaD_EyE: datetime und timedelta sind Klassen, die man nicht kryptisch Abkürzen sollte.
Vor allen dann, weil ich nicht für solche kleinen Sachen keine IDE verwende.
Außerdem kann es dazu führen, dass jemand danach fragt, was dieses from ... import foo as x überhaupt bedeutet.
Auch ein Lerneffekt ^^
Wenn der Code mehr als 100 Zeilen hat, ist das zu überblicken und mein Gehirn kann das noch so gerade eben verarbeiten.
Falls es mehr wird, steigt die Wahrscheinlichkeit, dass man dt und td irgendwas anderes zuweist.
Wenn das mal passiert, ist das auch gut. Nur wer Fehler macht, kann daraus lernen.
Mir ist schon klar, dass du es gerne so hättest, dass derjenige von Anfang an alles richtig lernt und sich keine schlechten Angewohnheiten verfestigen.
Bei anderen Modulen haben sich die Abkürzungen eingebürgert: numpy -> np, scipy -> sp, pandas -> pd, matplotlib.pyplot -> plt
Der OP hat nochmal die Frage gestellt, wie man Start- und Endzeitpunkt festlegen kann. Hier nochmal mein überarbeitetes Beispiel:
Code: Alles auswählen
import csv
import os
from datetime import datetime
from datetime import timedelta
from urllib.request import urlopen
import matplotlib.pyplot as plt
def chunked_download(url, dateiname):
with open (dateiname, "wb") as datei:
req = urlopen(url)
# nicht alles aufeinmal laden
while True:
chunk = req.read(64 * 1024)
if not chunk:
# keine Daten mehr, Datei zuende.
break
# Schreibe den block
datei.write(chunk)
def zeitstempel_umwandeln(datum, zeit):
datetime_format = '%d.%m.%Y %H:%M'
if '24:00' == zeit:
zeit = '00:00'
next_day = True
else:
next_day = False
zeitstempel = datum + " " + zeit
zeitstempel = datetime.strptime(zeitstempel, datetime_format)
if next_day:
zeitstempel += timedelta(days=1)
return zeitstempel
def werte_auslesen(dateiname, feld, start_datum, end_datum):
x = []
y = []
with open(dateiname) as datei:
next(datei) # 1. header überspringen
dict_reader = csv.DictReader(datei, delimiter=";")
for row in dict_reader:
datum = row["Datum"]
zeit = row["Zeit"]
zeitstempel = zeitstempel_umwandeln(datum, zeit)
if start_datum <= zeitstempel <= end_datum:
wert = row[feld].replace(",", ".")
if not wert:
continue
wert = float(wert)
x.append(zeitstempel)
y.append(wert)
return x, y
url = "https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/T_AM1H.csv"
dateiname = "Temperatur.csv"
feld = "BONN T AM1H [°C]"
if not os.path.exists(dateiname):
# nur herunterladen, falls die Datei fehlt
# Das schont den Server
# Sind nicht unsere Ressourcen
chunked_download(url, dateiname)
start = datetime(2019, 1, 29)
ende = datetime(2020, 1, 30)
x, y = werte_auslesen(dateiname, feld, start, ende)
# Für Matplotlib gibt es viele
# Tutorials
# Docs: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html#matplotlib.pyplot.plot
# Eigentlich soll man plt.plot und plt.plot_date nicht nutzen,
# sondern das objektorientierte Interface.
# Kommt daher, weil matplotlib an Matlab angelehnt ist.
plt.plot_date(x, y, '-')
plt.show()
Den Header, den ich mit next(datei) verwerfe, beinhaltet den Zeitraum: #ZEITBEREICH: 29.01.2019 bis 30.01.2020
Danach kommt der eigentliche Header mit den Feldnamen, den der DictReader automatisch liest.
Ich hoffe das ist den Herren jetzt so genehm.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
- __blackjack__
- User
- Beiträge: 14052
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@DeaD_EyE: Das Gegenteil von kryptischen Abkürzungen ist ja nicht immer alles voll auszuschreiben inklusive Modulnamen. Und auch den Lerneffekt mit dem ``as`` kann man ohne kryptische Abkürzungen erreichen. Zum Beispiel in dem man die Namen importiert und PEP8 konform umbenennt:
Das IDE-Argument zieht IMHO nicht, weil jeder Editor der sich zum Programmieren eignet, mindestens Autovervollständigung für das was bereits im aktuellen oder allen offenen Dateien steht, anbietet. Wenn man also einmal `DateTime` voll ausgeschrieben hat, braucht man das nur noch anzufangen und kann es dann vom Editor vervollständigen lassen. Vernünftige Editoren machen die Vervollständigung auch so, dass man Vorschläge für beliebige Zeichen aus dem Wort in der richtigen Reihenfolge eingetippt, bekommt. Für `DateTime` brauche ich nur `DT` eintippen um hier gerade in diesem Beitragstext als ersten Vorschlag `DateTime` zu bekommen. Man kann also problemlos `dt` und `td` tippen und am Ende `DateTime` und `TimeDelta` im Text stehen haben. Das beste aus beiden Welten: die kryptischen Abkürzungen ohne Vokale die man früher gelernt/gewohnt war tippen, und die guten verständlichen Namen die man auch früher schon hätte schreiben sollen als Ergebnis. 
`chunked_download()` erfindet das Rad neu, denn es gibt in der Standardbibliothek `urllib.request.urlretrieve()` was genau das schon macht. Wobei es das Ergebnis von `urlopen()` auch schliesst.
Code: Alles auswählen
from datetime import datetime as DateTime, timedelta as TimeDelta
`chunked_download()` erfindet das Rad neu, denn es gibt in der Standardbibliothek `urllib.request.urlretrieve()` was genau das schon macht. Wobei es das Ergebnis von `urlopen()` auch schliesst.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
- DeaD_EyE
- User
- Beiträge: 1240
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Den vorgeschlagenen import finde ich hässlich. Besser wäre dann in Klammern.
Wenn, dann würde ich es so schreiben:
Wer git kennt, weiß wieso.
Ich nutze sehr oft dumme Editoren für wenig Code, also zieht dein Argument nicht.
Ich weiß, dass diese Abkürzungen nicht aussagekräftig sind, wenn es mir aber Tipparbeit erspart, dann mache ich das so und werde mich dafür auch nicht 10 mal rechtfertigen.
Ich halte es z.B. für schädlich, wenn Anfänger eine IDE nutzen. Führt dazu, dass das Hirn faul wird und der Änfänger ohne IDE wie ein Ochse vorm Berg steht.
Das mit dem chunked_download kannte ich bis jetzt noch nicht.
Dann hoffe ich mal, dass ich das richtig implementiert habe
Wenn, dann würde ich es so schreiben:
Code: Alles auswählen
from datetime import (
datetime as DateTime,
timedelta as TimeDelta,
)
Ich nutze sehr oft dumme Editoren für wenig Code, also zieht dein Argument nicht.
Ich weiß, dass diese Abkürzungen nicht aussagekräftig sind, wenn es mir aber Tipparbeit erspart, dann mache ich das so und werde mich dafür auch nicht 10 mal rechtfertigen.
Ich halte es z.B. für schädlich, wenn Anfänger eine IDE nutzen. Führt dazu, dass das Hirn faul wird und der Änfänger ohne IDE wie ein Ochse vorm Berg steht.
Das mit dem chunked_download kannte ich bis jetzt noch nicht.
Dann hoffe ich mal, dass ich das richtig implementiert habe

sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
- __blackjack__
- User
- Beiträge: 14052
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@DeaD_EyE: Mein Argument zieht sehr wohl. Ich benutze für Python grundsätzlich keine IDE und so dumme Editoren gibt es heute nicht mehr. Wer unbedingt mit Notepad programmieren will hat selbst schuld. Syntaxhighlighting und Autovervollständigung kann heute jedes Programm das sich an Programmierer richtet, Editor nennt, und den Namen verdient.
Da der Import in eine Zeile passt in unter 80 Zeichen macht es keinen Sinn das auf mehrere Zeilen aufzuteilen. Sobald die Zeile 79 Zeichen überschritten hat wird es natürlich aufgeteilt auf einen Namen + eventuelle Umbenennung mit ``as`` pro Zeile. Und ich habe da auch keine Wahl und will die auch gar nicht haben, denn ich will mich damit nicht beschäftigen müssen → das macht mein Editor/das `black`-Plugin. Und `black` hat genau zwei Einstellungen: die maximale Zeilenlänge und ob ' in " umgewandelt werden sollen wenn der Code dadurch nicht länger wird oder nicht. Sind für meinen Geschmack sogar zwei Einstellungen zu viel, ich könnte auch mit 79 und Ja leben.
Da der Import in eine Zeile passt in unter 80 Zeichen macht es keinen Sinn das auf mehrere Zeilen aufzuteilen. Sobald die Zeile 79 Zeichen überschritten hat wird es natürlich aufgeteilt auf einen Namen + eventuelle Umbenennung mit ``as`` pro Zeile. Und ich habe da auch keine Wahl und will die auch gar nicht haben, denn ich will mich damit nicht beschäftigen müssen → das macht mein Editor/das `black`-Plugin. Und `black` hat genau zwei Einstellungen: die maximale Zeilenlänge und ob ' in " umgewandelt werden sollen wenn der Code dadurch nicht länger wird oder nicht. Sind für meinen Geschmack sogar zwei Einstellungen zu viel, ich könnte auch mit 79 und Ja leben.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
- __blackjack__
- User
- Beiträge: 14052
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Was die Implementierung von `chunked_download()` angeht: Wie gesagt wird `req` nicht geschlossen. Und natürlich ist `req` wieder ein schlechter Name, weil Abkürzungen eben so leicht falsch interpretiert werden können. Man könnte das zum Beispiel leicht als `request` missverstehen, was sicher nicht gemeint war, denn das Objekt ist ja keine Anfrage („request“) sondern eine Antwort („response“) vom Typ `http.client.HTTPResponse` wenn das URL-Schema HTTP(S) war. Wofür sollte `req` denn ausgeschrieben stehen?
Und die Schleife zum Inhalt von Dateiobjekten kopieren gibt es als `shutil.copyfileobj()` in der Standardbibliothek:
Was `urlretrieve()` aus der Standardbibliothek noch zusätlich macht, ist schauen ob es den HTTP-Header „Content-Length“ in der Server-Antwort gibt und am Ende vergleichen ob die gelesene Länge mit der im Header angegebenen übereinstimmt. Falls der Server vorzeitig mit dem Senden aufgehört hat, bekommt man eine Ausnahme.
Und die Schleife zum Inhalt von Dateiobjekten kopieren gibt es als `shutil.copyfileobj()` in der Standardbibliothek:
Code: Alles auswählen
def chunked_download(url, dateiname):
with open(dateiname, "wb") as datei:
with urlopen(url) as response:
copyfileobj(response, datei)
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Hallo, ich hab dies nun weiter verarbeitet.
nun bekomme ich graphen für die jeweiligen Messwerte für bonn raus.
Heißt : Der Benutzer kann auswählen welche Messwert er haben möchte für Bonn
Nun will ich aber den Graphen nicht für 360 Tage sondern so, das der nutzer wählen kann wenn er z.b Messwert Temperatur gewählt hat, wie viele Tage er den Graphen haben möchte z.b für 7 tage ...
Also von 1 Tag bis 360 Tage...
Ich hoffe ihr könnt mir helfen
So weit bin ich :
import csv
from datetime import datetime as dt
from datetime import timedelta as td
from urllib.request import urlopen
import matplotlib.pyplot as plt
#Vorstellung
print("Grafische Darstellung von Wetterdaten \n"
f"--------------------------------------\n\n"
f"Dieses Programm erzeugt ein Diagramm mit\n"
"aktuellen Wetterdaten der letzten Tage für Bonn. \n"
f"Gib an, für welchen Messwert das Diagramm angezeigt werden \n"
f"soll und wie viele Tage berücksichtig werden sollen. \n\n"
f"Folgende Messwerte stehen zur Auswahl: \n\n"
f"\t Wetterdaten \n"
f"\t -----------\n\n"
f" 0) Temperatur \n"
f" 1) Relative Luftfeuchtigkeit \n"
f" 2) Windgeschwindigkeit \n"
f" 3) Windrichtung \n\n"
f"\t Schadstoffe \n"
f"\t -----------\n\n"
f" 4) Stickstoffmonoxid (NO)\n"
f" 5) Stickstoffdioxid (NO3)\n"
f" 6) Partikel PM10 \n")
#Input für User
Messwert = int(input("Gib die Kennziffer des gewünschten Messwertes ein: "))
#Solange Messwert nicht 0 - 6
while Messwert not in (range(0, 7)):
print("\nDiese Kenziffer existiert nicht. \n")
#Wiederholung wenn Messwert nicht 0 - 6
Messwert = int(input("Gib die Kennziffer des gewünschten Messwertes ein: "))
#---------------------------Temperatur-------------------------------------
if Messwert == 0:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... T_AM1H.csv")
stadt = "BONN T AM1H [°C]"
dateiname = "Temperatur.csv"
print("\nSie haben die Auswertung für Messwert „Temperatur“ gewählt.")
#---------------------------Relative Luftfeuchtigkeit----------------------
elif Messwert == 1:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... F_AM1H.csv")
stadt = "BONN F AM1H [%]"
dateiname = "RelativeLuftfeuchtigkeit.csv"
print("\nSie haben die Auswertung für Messwert „Relative Luftfeuchtigkeit“ gewählt.")
#---------------------------Windgeschwindigkeit----------------------------
elif Messwert == 2:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... G_SM1H.csv")
stadt = "BONN WG SM1H [m/s]"
dateiname = "Windgeschwindigkeit.csv"
print("\nSie haben die Auswertung für Messwert „Windgeschwindigkeit“ gewählt.")
#---------------------------Windrichtung-----------------------------------
elif Messwert == 3:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... R_VM1H.csv")
stadt = "BONN WR VM1H [°]"
dateiname = "Windrichtung.csv"
print("\nSie haben die Auswertung für Messwert „Windrichtung“ gewählt.")
#---------------------------Stickstoffmonoxid (NO)-------------------------
elif Messwert == 4:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... O_AM1H.csv")
stadt ="BONN NO AM1H [µg/m³]"
dateiname = "Stickstoffmonoxid.csv"
print("\nSie haben die Auswertung für Messwert „Stickstoffmonoxid (NO)“ gewählt.")
#---------------------------Stickstoffdioxid (NO2)-------------------------
elif Messwert == 5:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... 2_AM1H.csv")
stadt ="BONN NO2 AM1H [µg/m³]"
dateiname = "Stickstoffdioxid.csv"
print("\nSie haben die Auswertung für Messwert „Stickstoffdioxid (NO2)“ gewählt.")
#---------------------------Partikel PM10----------------------------------
elif Messwert == 6:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... _GM24H.csv")
stadt ="BONN PM10F GM24H [µg/m³]"
dateiname = "Partikel.csv"
print("\nSie haben die Auswertung für Messwert „Partikel PM10“ gewählt.")
#If = wenn Messwert = 0 Temperatur ausführen
#elif = -> Oder (Fall unterscheidung)
#else wäre -> UND
with open (dateiname, "wb") as datei:
req = urlopen(url)
# nicht alles aufeinmal laden
while True:
chunk = req.read(64 * 1024)
if not chunk:
# keine Daten mehr, Datei zuende.
break
# Schreibe den block
datei.write(chunk)
dt_format = '%d.%m.%Y %H:%M'
with open(dateiname) as datei:
next(datei)
# next(datei) überspringen der 1. Zeile
zeile = csv.DictReader(datei, delimiter=";")
# der DictReader bekommt als erstes Argument das Dateiobjekt
# dieser liest dann die erste Zeile mit den Feldnamen ein.
# Da der Kommentar bereits übersprungen ist, funktioniert das
datumlist = []
wertlist = []
for row in zeile:
werte = row[stadt].replace(",", ".")
#Alle
if "<10" == werte:
werte = "5"
elif "<7" == werte:
werte = "3"
#da bei Stickstoffmonoxid und Partike PM10 "<10 und <7"
#auftauchen und nicht gefloutet werden können,
#ersetze <10 mit 5 und <7 mit 3
elif not werte:
# wenn kein Wert vorhanden ist (Leerzeile),
# dann überspringen
continue
datum = row["Datum"]
zeit = row["Zeit"]
# offensichtlich kommt auch 24 Uhr in den Datensätzen vor
# das wäre dann schon der nächste Tag
# 24:00 lässt sich aber nicht parsen
# also setze ich das auf 00:00 und
# füge einen Tag hinzu.
if '24:00' == zeit:
zeit = '00:00'
next_day = True
else:
next_day = False
zeitstempel = datum + " " + zeit
# Hier tritt ein Fehler auf, wenn die Zeitangabe
# ungültig ist
# ggf. mit try... except abfangen und überspringen
zeitstempel = dt.strptime(zeitstempel, dt_format)
# nächster Tag
if next_day:
zeitstempel += td(days=1)
# Deutsch > Englisch
# float("1,5") geht z.b. nicht
# deswegen , durch . ersetzen
# Wert auslesen und Komma durch Punkt ersetzen
# Wert in float umwandeln
# Bei der Umwandlung kann es zu einem ValueError
# kommen, sofern der string nicht in einen float
# umgewandelt werden kann
# auch hier, kann man mit try und except den Fehler
# abfangen und entsprechend reagieren.
werte = float(werte)
# wert zur Liste hinzufügen
wertlist.append(werte)
datumlist.append(zeitstempel)
plt.plot_date(datumlist, wertlist,'-')
plt.show()
nun bekomme ich graphen für die jeweiligen Messwerte für bonn raus.
Heißt : Der Benutzer kann auswählen welche Messwert er haben möchte für Bonn
Nun will ich aber den Graphen nicht für 360 Tage sondern so, das der nutzer wählen kann wenn er z.b Messwert Temperatur gewählt hat, wie viele Tage er den Graphen haben möchte z.b für 7 tage ...
Also von 1 Tag bis 360 Tage...
Ich hoffe ihr könnt mir helfen
So weit bin ich :
import csv
from datetime import datetime as dt
from datetime import timedelta as td
from urllib.request import urlopen
import matplotlib.pyplot as plt
#Vorstellung
print("Grafische Darstellung von Wetterdaten \n"
f"--------------------------------------\n\n"
f"Dieses Programm erzeugt ein Diagramm mit\n"
"aktuellen Wetterdaten der letzten Tage für Bonn. \n"
f"Gib an, für welchen Messwert das Diagramm angezeigt werden \n"
f"soll und wie viele Tage berücksichtig werden sollen. \n\n"
f"Folgende Messwerte stehen zur Auswahl: \n\n"
f"\t Wetterdaten \n"
f"\t -----------\n\n"
f" 0) Temperatur \n"
f" 1) Relative Luftfeuchtigkeit \n"
f" 2) Windgeschwindigkeit \n"
f" 3) Windrichtung \n\n"
f"\t Schadstoffe \n"
f"\t -----------\n\n"
f" 4) Stickstoffmonoxid (NO)\n"
f" 5) Stickstoffdioxid (NO3)\n"
f" 6) Partikel PM10 \n")
#Input für User
Messwert = int(input("Gib die Kennziffer des gewünschten Messwertes ein: "))
#Solange Messwert nicht 0 - 6
while Messwert not in (range(0, 7)):
print("\nDiese Kenziffer existiert nicht. \n")
#Wiederholung wenn Messwert nicht 0 - 6
Messwert = int(input("Gib die Kennziffer des gewünschten Messwertes ein: "))
#---------------------------Temperatur-------------------------------------
if Messwert == 0:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... T_AM1H.csv")
stadt = "BONN T AM1H [°C]"
dateiname = "Temperatur.csv"
print("\nSie haben die Auswertung für Messwert „Temperatur“ gewählt.")
#---------------------------Relative Luftfeuchtigkeit----------------------
elif Messwert == 1:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... F_AM1H.csv")
stadt = "BONN F AM1H [%]"
dateiname = "RelativeLuftfeuchtigkeit.csv"
print("\nSie haben die Auswertung für Messwert „Relative Luftfeuchtigkeit“ gewählt.")
#---------------------------Windgeschwindigkeit----------------------------
elif Messwert == 2:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... G_SM1H.csv")
stadt = "BONN WG SM1H [m/s]"
dateiname = "Windgeschwindigkeit.csv"
print("\nSie haben die Auswertung für Messwert „Windgeschwindigkeit“ gewählt.")
#---------------------------Windrichtung-----------------------------------
elif Messwert == 3:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... R_VM1H.csv")
stadt = "BONN WR VM1H [°]"
dateiname = "Windrichtung.csv"
print("\nSie haben die Auswertung für Messwert „Windrichtung“ gewählt.")
#---------------------------Stickstoffmonoxid (NO)-------------------------
elif Messwert == 4:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... O_AM1H.csv")
stadt ="BONN NO AM1H [µg/m³]"
dateiname = "Stickstoffmonoxid.csv"
print("\nSie haben die Auswertung für Messwert „Stickstoffmonoxid (NO)“ gewählt.")
#---------------------------Stickstoffdioxid (NO2)-------------------------
elif Messwert == 5:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... 2_AM1H.csv")
stadt ="BONN NO2 AM1H [µg/m³]"
dateiname = "Stickstoffdioxid.csv"
print("\nSie haben die Auswertung für Messwert „Stickstoffdioxid (NO2)“ gewählt.")
#---------------------------Partikel PM10----------------------------------
elif Messwert == 6:
url = ("https://www.lanuv.nrw.de/fileadmin/lanu ... _GM24H.csv")
stadt ="BONN PM10F GM24H [µg/m³]"
dateiname = "Partikel.csv"
print("\nSie haben die Auswertung für Messwert „Partikel PM10“ gewählt.")
#If = wenn Messwert = 0 Temperatur ausführen
#elif = -> Oder (Fall unterscheidung)
#else wäre -> UND
with open (dateiname, "wb") as datei:
req = urlopen(url)
# nicht alles aufeinmal laden
while True:
chunk = req.read(64 * 1024)
if not chunk:
# keine Daten mehr, Datei zuende.
break
# Schreibe den block
datei.write(chunk)
dt_format = '%d.%m.%Y %H:%M'
with open(dateiname) as datei:
next(datei)
# next(datei) überspringen der 1. Zeile
zeile = csv.DictReader(datei, delimiter=";")
# der DictReader bekommt als erstes Argument das Dateiobjekt
# dieser liest dann die erste Zeile mit den Feldnamen ein.
# Da der Kommentar bereits übersprungen ist, funktioniert das
datumlist = []
wertlist = []
for row in zeile:
werte = row[stadt].replace(",", ".")
#Alle
if "<10" == werte:
werte = "5"
elif "<7" == werte:
werte = "3"
#da bei Stickstoffmonoxid und Partike PM10 "<10 und <7"
#auftauchen und nicht gefloutet werden können,
#ersetze <10 mit 5 und <7 mit 3
elif not werte:
# wenn kein Wert vorhanden ist (Leerzeile),
# dann überspringen
continue
datum = row["Datum"]
zeit = row["Zeit"]
# offensichtlich kommt auch 24 Uhr in den Datensätzen vor
# das wäre dann schon der nächste Tag
# 24:00 lässt sich aber nicht parsen
# also setze ich das auf 00:00 und
# füge einen Tag hinzu.
if '24:00' == zeit:
zeit = '00:00'
next_day = True
else:
next_day = False
zeitstempel = datum + " " + zeit
# Hier tritt ein Fehler auf, wenn die Zeitangabe
# ungültig ist
# ggf. mit try... except abfangen und überspringen
zeitstempel = dt.strptime(zeitstempel, dt_format)
# nächster Tag
if next_day:
zeitstempel += td(days=1)
# Deutsch > Englisch
# float("1,5") geht z.b. nicht
# deswegen , durch . ersetzen
# Wert auslesen und Komma durch Punkt ersetzen
# Wert in float umwandeln
# Bei der Umwandlung kann es zu einem ValueError
# kommen, sofern der string nicht in einen float
# umgewandelt werden kann
# auch hier, kann man mit try und except den Fehler
# abfangen und entsprechend reagieren.
werte = float(werte)
# wert zur Liste hinzufügen
wertlist.append(werte)
datumlist.append(zeitstempel)
plt.plot_date(datumlist, wertlist,'-')
plt.show()
Ich hab es bisschen weiter verarbeitet. und den graph übersichtlicher gemacht.
Brauche jetzt wie gesagt : Der User soll nun nach dem aussuchen des Messwertes, die Tage auswählen können, die er geplottet bekommen soll..
Da weiß ich leider auch nicht weiter.
Außerdem muss ich noch Valueerror beim eintippen eines NICHT INTIGERS ( Buchstaben, in den Messwert = Int(input..) beheben, dort bin ich auch noch nicht weiter gekomen
Brauche jetzt wie gesagt : Der User soll nun nach dem aussuchen des Messwertes, die Tage auswählen können, die er geplottet bekommen soll..
Da weiß ich leider auch nicht weiter.
Außerdem muss ich noch Valueerror beim eintippen eines NICHT INTIGERS ( Buchstaben, in den Messwert = Int(input..) beheben, dort bin ich auch noch nicht weiter gekomen
Code: Alles auswählen
import csv
import matplotlib.dates as md
import matplotlib.ticker as mt
#Zeit angaben
from datetime import datetime as dt
from datetime import timedelta as td
#Downloaden der CSV datei
from urllib.request import urlopen
#Für Random Zahl
from random import *
#Matplotlib
import matplotlib.pyplot as plt
#Vorstellung
print("Grafische Darstellung von Wetterdaten \n"
f"--------------------------------------\n\n"
f"Dieses Programm erzeugt ein Diagramm mit\n"
"aktuellen Wetterdaten der letzten Tage für Bonn. \n"
f"Gib an, für welchen Messwert das Diagramm angezeigt werden \n"
f"soll und wie viele Tage berücksichtig werden sollen. \n\n"
f"Folgende Messwerte stehen zur Auswahl: \n\n"
f"\t Wetterdaten \n"
f"\t -----------\n\n"
f" 0) Temperatur \n"
f" 1) Relative Luftfeuchtigkeit \n"
f" 2) Windgeschwindigkeit \n"
f" 3) Windrichtung \n\n"
f"\t Schadstoffe \n"
f"\t -----------\n\n"
f" 4) Stickstoffmonoxid (NO)\n"
f" 5) Stickstoffdioxid (NO3)\n"
f" 6) Partikel PM10 \n")
#Input für User
#int = Integer -> NUR ZAHL
try:
Messwert = int(input("Gib die Kennziffer des gewünschten Messwertes ein: "))
except(ValueError):
print("\nDies ist leider keine Kennziffer. \n")
Messwert = int(input("Gib die Kennziffer des gewünschten Messwertes ein: "))
#Solange Messwert nicht 0 - 6
while Messwert not in (range(0, 7)):
print("\nDiese Kenziffer existiert nicht. \n")
#Wiederholung wenn Messwert nicht 0 - 6
Messwert = int(input("Gib die Kennziffer des gewünschten Messwertes ein: "))
#---------------------------Temperatur-------------------------------------
if Messwert == 0:
url = ("https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/T_AM1H.csv")
stadt = "BONN T AM1H [°C]"
dateiname = "Temperatur.csv"
labelname = "Temperatur"
MesswertEinheit = "Messwert in °C"
print("\nSie haben die Auswertung für Messwert „Temperatur“ gewählt.")
#---------------------------Relative Luftfeuchtigkeit----------------------
elif Messwert == 1:
url = ("https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/F_AM1H.csv")
stadt = "BONN F AM1H [%]"
dateiname = "RelativeLuftfeuchtigkeit.csv"
labelname = "Relative Luftfeuchtigkeit"
MesswertEinheit = "Messwert in °C"
print("\nSie haben die Auswertung für Messwert „Relative Luftfeuchtigkeit“ gewählt.")
#---------------------------Windgeschwindigkeit----------------------------
elif Messwert == 2:
url = ("https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/WG_SM1H.csv")
stadt = "BONN WG SM1H [m/s]"
dateiname = "Windgeschwindigkeit.csv"
labelname ="Windgeschwindigkeit"
MesswertEinheit = "Messwert in m/s"
print("\nSie haben die Auswertung für Messwert „Windgeschwindigkeit“ gewählt.")
#---------------------------Windrichtung-----------------------------------
elif Messwert == 3:
url = ("https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/WR_VM1H.csv")
stadt = "BONN WR VM1H [°]"
dateiname = "Windrichtung.csv"
labelname ="Windrichtung"
MesswertEinheit = "Messwert"
print("\nSie haben die Auswertung für Messwert „Windrichtung“ gewählt.")
#---------------------------Stickstoffmonoxid (NO)-------------------------
elif Messwert == 4:
url = ("https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/NO_AM1H.csv")
stadt ="BONN NO AM1H [µg/m³]"
dateiname = "Stickstoffmonoxid.csv"
labelname ="Stickstoffmonoxid (NO)"
MesswertEinheit = "Messwert in µg/m³"
print("\nSie haben die Auswertung für Messwert „Stickstoffmonoxid (NO)“ gewählt.")
#---------------------------Stickstoffdioxid (NO2)-------------------------
elif Messwert == 5:
url = ("https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/NO2_AM1H.csv")
stadt ="BONN NO2 AM1H [µg/m³]"
dateiname = "Stickstoffdioxid.csv"
labelname ="Stickstoffdioxid (NO2)"
MesswertEinheit = "Messwert in µg/m³"
print("\nSie haben die Auswertung für Messwert „Stickstoffdioxid (NO2)“ gewählt.")
#---------------------------Partikel PM10----------------------------------
elif Messwert == 6:
url = ("https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/PM10F_GM24H.csv")
stadt ="BONN PM10F GM24H [µg/m³]"
dateiname = "Partikel.csv"
labelname ="Partikel PM10"
MesswertEinheit = "Messwert in µg/m³"
print("\nSie haben die Auswertung für Messwert „Partikel PM10“ gewählt.")
#If = wenn Messwert = 0 Temperatur ausführen
#elif = -> Oder (Fall unterscheidung)
#else wäre -> UND
#CSV-Datei herunterladen
with open(dateiname, "wb") as datei:
datei.write(urlopen(url).read())
with open(dateiname, encoding="ansi") as datei:
next(datei)
# next(datei) überspringen der 1. Zeile
zeile = csv.DictReader(datei, delimiter=";")
# dieser liest dann die erste Zeile mit den Feldnamen ein.
datumlist = []
wertlist = []
for row in zeile:
werte = row[stadt].replace(",", ".")
#Alle
if "<10" == werte:
werte = randint(0,9)
elif "<7" == werte:
werte = randint(0,6)
#da bei Stickstoffmonoxid und Partike PM10 "<10 und <7"
#auftauchen und nicht gefloutet werden können,
#ersetze <10 mit einer Zufälligen Zahl zwischen 0 - 10
#und <7 mit einer Zufälligen Zahl zwischen 0 - 6
elif not werte:
werte == 0
# wenn kein Wert vorhanden ist,
# dann = 0 setzen
continue
datum = row["Datum"]
zeit = row["Zeit"]
#Da wir 24:00 uhr schon der nächste Tag ist,
#Setzte ich es zu 00:00
if '24:00' == zeit:
zeit = '00:00'
next_day = True
else:
next_day = False
zeitstempel = datum + " " + zeit
#Datum und Zeit werden in einer einzigen Zeitangabe
#zusammengebaut -> numerischen Datumswert ungeformt
zeitstempel = dt.strptime(zeitstempel, '%d.%m.%Y %H:%M')
# nächster Tag
if next_day:
zeitstempel += td(days=1)
werte = float(werte)
# wert zur Liste hinzufügen
wertlist.append(werte)
datumlist.append(zeitstempel)
# Größe auf dem Bildschirm vorgeben, hier ungefähr 8 mal 6 Zoll:
fig, ax = plt.subplots(figsize=(10,6))
# Überschrift:
plt.title(labelname)
# Messkurve, mit Label für Legende, einzeichnen:
plt.plot(datumlist, wertlist, label=labelname )
plt.xlabel("Datum")
plt.ylabel(MesswertEinheit)
# Die gewünschte Datumsformatierung der x-Achse definieren.
ax.xaxis.set_major_formatter(md.DateFormatter("%d.%m.%Y"))
# Für die untergeordneten Teilstriche kann man zusätzlich eine „minor“
# Formatierung festlegen.
# Diese Teilstriche sollen hier beispielsweise 0.5°C auflösen.
ax.yaxis.set_minor_locator(mt.MultipleLocator(0.5))
# Datumsbeschriftung der x-Achse um 30° drehen:
fig.autofmt_xdate(rotation=30)
# Den überflüssigen Freiraum vor und hinter der Diagrammkurve abschneiden:
plt.xlim(datumlist[0],datumlist[-1])
# Ein Raster erleichtert das Ablesen.
plt.grid(color="lightgrey")
# Eine Legende hinzufügen:
plt.legend()
# Vorhandenen Platz optimal ausnutzen, unnötige Ränder entfernen,
# Überlappen von Grafikelementen verhindern:
plt.tight_layout()
# Zeigt Plot an
plt.show()
Jetzt hast Du ja noch mehr kryptische zweibuchstabige Abkürzungen, mt, md, dt, td da kann man sich leicht mal vertippen. Um so mehr, dass man damit exakt einmal sich ein paar Tasten spart.
Keine *-Importe sondern immer nur explizit. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2 oder 3.
Dann vertragen die 200 Zeilen ein paar Funktionsdefinitionen. Namenskonvention für Variablen ist klein_mit_unterstrich: messwert_einheit
Die ganzen f-Strings haben keine Formatangaben.
Kodewiederholungen vermeiden: Du hast dreimal die identische Zeile »Messwert = ...«, statt dessen solltest Du eine while-True-Schleife benutzen und diese bei korrekter Eingabe verlassen. ›except‹ ist keine Funktion, da braucht es keine Klammern.
Die lange if-elif-Kaskade solltest Du doch eine passende Datenstruktur ersetzen.
Verbindungen, die man mit urlopen öffnet, sollte man auch wieder schließen.
Typenbezeichner sollten nicht in Variablennamen vorkommen, also `werte` statt `wertlist`, wobei dann später die Variable `werte` für einen Wert natürlich auch repariert werden muß.
`zeile` für viele Zeilen ist dann wiederum andersherum falsch.
Beim Plotten nutzt Du plt statt fig bzw. ax.
Keine *-Importe sondern immer nur explizit. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2 oder 3.
Dann vertragen die 200 Zeilen ein paar Funktionsdefinitionen. Namenskonvention für Variablen ist klein_mit_unterstrich: messwert_einheit
Die ganzen f-Strings haben keine Formatangaben.
Kodewiederholungen vermeiden: Du hast dreimal die identische Zeile »Messwert = ...«, statt dessen solltest Du eine while-True-Schleife benutzen und diese bei korrekter Eingabe verlassen. ›except‹ ist keine Funktion, da braucht es keine Klammern.
Die lange if-elif-Kaskade solltest Du doch eine passende Datenstruktur ersetzen.
Verbindungen, die man mit urlopen öffnet, sollte man auch wieder schließen.
Typenbezeichner sollten nicht in Variablennamen vorkommen, also `werte` statt `wertlist`, wobei dann später die Variable `werte` für einen Wert natürlich auch repariert werden muß.
`zeile` für viele Zeilen ist dann wiederum andersherum falsch.
Beim Plotten nutzt Du plt statt fig bzw. ax.
Ganz herzlichen Dank an DeaD_EyE, Sirius3 und __blackjack__ für das geduldige Beantworten der Fragen zu der von mir gestellten Hausaufgabe :-)
Liebe mitlesende Studierende, vergesst bitte nicht, in der Dokumentation eine ordentliche Quellenangabe vorzunehmen!
Liebe mitlesende Studierende, vergesst bitte nicht, in der Dokumentation eine ordentliche Quellenangabe vorzunehmen!
- __blackjack__
- User
- Beiträge: 14052
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Was glaube ich noch nicht erwähnt wurde ist das "ansi" eine ungünstige Wahl als Kodierung ist, denn das funktioniert nur unter Windows, und ich sehe nicht warum man das nicht so schreiben sollte, dass es auch unter Linux, MacOS, … laufen kann.
Hier mal eine überarbeitete Version:
Das die "<n" Angaben durch eine zufällige *ganze* Zahl ersetzt werden finde ich komisch.
Die `MeasurementDescription` sind auch recht redundant aufgebaut. Der Dateiname vom Server kommt im Spaltennamen vor und die Einheit auch. Da könnte man beispielsweise den Spaltennamen aus Dateiname auf dem Server und Einheit berechnen.
Hier mal eine überarbeitete Version:
Code: Alles auswählen
#!/usr/bin/env python3
import csv
import os
from collections import namedtuple
from datetime import datetime as DateTime, timedelta as TimeDelta
from random import randrange
from urllib.request import urlretrieve
from matplotlib import pyplot as plt
from matplotlib.dates import DateFormatter
from matplotlib.ticker import MultipleLocator
BASE_URL = "https://www.lanuv.nrw.de/fileadmin/lanuv/luft/temes/"
MeasurementDescription = namedtuple(
"MeasurementDescription",
"name remote_filename column_name local_filename unit",
)
MEASUREMENT_DESCRIPTIONS = [
MeasurementDescription(
"Temperatur", "T_AM1H.csv", "BONN T AM1H [°C]", "Temperatur.csv", "°C"
),
MeasurementDescription(
"Relative Luftfeuchtigkeit",
"F_AM1H.csv",
"BONN F AM1H [%]",
"RelativeLuftfeuchtigkeit.csv",
"%",
),
MeasurementDescription(
"Windgeschwindigkeit",
"WG_SM1H.csv",
"BONN WG SM1H [m/s]",
"Windgeschwindigkeit.csv",
"m/s",
),
MeasurementDescription(
"Windrichtung",
"WR_VM1H.csv",
"BONN WR VM1H [°]",
"Windrichtung.csv",
"°",
),
MeasurementDescription(
"Stickstoffmonoxid (NO)",
"NO_AM1H.csv",
"BONN NO AM1H [µg/m³]",
"Stickstoffmonoxid.csv",
"µg/m³",
),
MeasurementDescription(
"Stickstoffdioxid (NO2)",
"NO2_AM1H.csv",
"BONN NO2 AM1H [µg/m³]",
"Stickstoffdioxid.csv",
"µg/m³",
),
MeasurementDescription(
"Partikel PM10",
"PM10F_GM24H.csv",
"BONN PM10F GM24H [µg/m³]",
"Partikel.csv",
"µg/m³",
),
]
def ask_for_measurement_description():
print(
"Grafische Darstellung von Wetterdaten \n"
"--------------------------------------\n\n"
"Dieses Programm erzeugt ein Diagramm mit\n"
"aktuellen Wetterdaten der letzten Tage für Bonn.\n"
"Gib an, für welchen Messwert das Diagramm angezeigt werden\n"
"soll und wie viele Tage berücksichtig werden sollen.\n\n"
"Folgende Messwerte stehen zur Auswahl:\n"
)
for i, description in enumerate(MEASUREMENT_DESCRIPTIONS):
print(f"{i:>3}) {description.name}")
print()
while True:
try:
index = int(
input("Gib die Kennziffer des gewünschten Messwertes ein: ")
)
except ValueError:
print("\nDies ist leider keine Kennziffer. \n")
else:
if 0 <= index < len(MEASUREMENT_DESCRIPTIONS):
description = MEASUREMENT_DESCRIPTIONS[index]
print(
f"\nSie haben die Auswertung für Messwert"
f" „{description.name}“ gewählt."
)
return description
print("\nDiese Kenziffer existiert nicht. \n")
def parse_value(string):
string = string.strip().replace(",", ".")
if not string:
return None
#
# Da bei Stickstoffmonoxid und Partikel PM10 "<10" und "<7"
# auftauchen und nicht gefloutet werden können, ersetze "<n" mit
# einer zufälligen Zahl zwischen 0 und n-1.
#
return (
randrange(int(string[1:])) if string.startswith("<") else float(string)
)
def parse_timestamp(date_string, time_string):
#
# Statt 00:00 Uhr gibt es 24:00 Uhr was 00:00 Uhr am nächsten
# Tag entspricht.
#
date_needs_adjustment = time_string == "24:00"
if date_needs_adjustment:
time_string = "00:00"
timestamp = DateTime.strptime(
f"{date_string} {time_string}", "%d.%m.%Y %H:%M"
)
if date_needs_adjustment:
timestamp += TimeDelta(days=1)
return timestamp
def load_data(filename, column_name):
with open(filename, encoding="latin-1") as datei:
next(datei) # Kommentarzeile am Dateianfang überspringen.
timestamps = list()
values = list()
for row in csv.DictReader(datei, delimiter=";"):
value = parse_value(row[column_name])
if value is not None:
timestamps.append(parse_timestamp(row["Datum"], row["Zeit"]))
values.append(value)
assert len(values) == len(timestamps)
return timestamps, values
def plot_data(timestamps, values, title, unit):
figure, axes = plt.subplots(figsize=(10, 6))
plt.title(title)
plt.plot(timestamps, values, label=title)
plt.xlabel("Datum")
plt.ylabel(f"Messwerte in {unit}")
axes.xaxis.set_major_formatter(DateFormatter("%d.%m.%Y"))
axes.yaxis.set_minor_locator(MultipleLocator(0.5))
figure.autofmt_xdate(rotation=30)
plt.xlim(timestamps[0], timestamps[-1])
plt.grid(color="lightgrey")
plt.legend()
plt.tight_layout()
plt.show()
def main():
description = ask_for_measurement_description()
if not os.path.exists(description.local_filename):
urlretrieve(
BASE_URL + description.remote_filename, description.local_filename
)
timestamps, values = load_data(
description.local_filename, description.column_name
)
plot_data(timestamps, values, description.name, description.unit)
if __name__ == "__main__":
main()
Die `MeasurementDescription` sind auch recht redundant aufgebaut. Der Dateiname vom Server kommt im Spaltennamen vor und die Einheit auch. Da könnte man beispielsweise den Spaltennamen aus Dateiname auf dem Server und Einheit berechnen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari