@tmessers: Anmerkungen zum Quelltext:
`time` wird importiert, aber nicht verwendet.
Eingerückt wird in Python vier Leerzeichen pro Ebene, nicht zwei.
Nach Kommas und um binäre Operatoren erhöhen Leerzeichen die Lesbarkeit. Den ``%``-Operator hast Du anscheinend immer an den zweiten Operanden gesetzt, und bei einfachen Zuweisungen immer unnötige Klammern um den Ausdruck gesetzt‽
``%`` würde ich in neuem Code auch nicht mehr zur Zeichenkettenformatierung verwenden wenn es dafür nicht einen guten Grund gibt. Es gibt die `format()`-Methode und ab Python 3.6 f-Zeichenkettenliterale.
Die Auswahl der Zeilen nach Nummern wäre mir nicht robust genug. Ich würde da die erste Spalte zum Index machen und über die Namen zugreifen.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). `Frage` würde also klein geschrieben. Aber es ist gar keine Frage sondern eine Antwort.
Das Datum erst in eine Zeichenkette zu wandeln nur um es danach zu parsen ist unsinnig. Stattdessen sollte man einfach aus der Benutzereingabe gleich ein `datetime.date`-Objekt oder ein `pandas.Timestamp`-Objekt erstellen.
Namen sollten keine kryptischen Abkürzungen enthalten. Die ganzen "wert_???"-Namen mit den dreibuchstabigen Stadt-/Landkreisabkürzungen sind schlecht. Das sollten auch gar keine einzelnen Namen sein, denn man kann die erste Zeile einfach an den Namen `aktuelle_fallzahlen` binden und auch Pandas gleich zum Umwandeln nach `int` verwenden:
Code: Alles auswählen
In [66]: df.iloc[0].astype(int)
Out[66]:
Freiburg 921
Breisg.-Hochschw. 1019
Baden-Baden 164
Ortenau 936
Rastatt 473
Name: 2020-04-22 00:00:00, dtype: int64
Für die `annotate()`-Aufrufe kann man dann eine Schleife über dieser Werte und die dazugehörigen Farben schreiben.
Apropos Farben: Die sollten da nicht so fest kodiert im Quelltext stehen, denn die hängen vom Farbschema ab. Wenn man die aus dem Plot von den Linien abfragt, ist man vom Farbschema unabhängig und bekommt dort immer die passenden Farben. Und man ist dann auch von der Anzahl der ausgewählten Stadt-/Landkreise unabhängig und kann ganz einfach welche hinzufügen oder weglassen, ohne den restlichen Code ändern zu müssen.
Code: Alles auswählen
#!/usr/bin/env python3
from datetime import date as Date
import matplotlib.pyplot as plt
import pandas as pd
EXCEL_FILE_URL = (
"https://sozialministerium.baden-wuerttemberg.de/"
"fileadmin/redaktion/m-sm/intern/downloads/Downloads_Gesundheitsschutz/"
"Tabelle_Coronavirus-Faelle-BW.xlsx"
)
def main():
#
# Paare: (Bezeichnung in Quelle, kürzere Bezeichnung für den Plot).
#
stadt_und_landkreise = [
("Freiburg im Breisgau (Stadtkreis)", "Freiburg"),
("Breisgau-Hochschwarzwald", "Breisg.-Hochschw."),
("Baden-Baden (Stadtkreis)", "Baden-Baden"),
("Ortenaukreis", "Ortenau"),
("Rastatt", "Rastatt"),
]
df_auswahl = (
pd.read_excel(EXCEL_FILE_URL, header=6, index_col=0)
.loc[[bezeichnung for bezeichnung, _ in stadt_und_landkreise], :]
.transpose()
)
df_auswahl.columns = [
kurz_bezeichnung for _, kurz_bezeichnung in stadt_und_landkreise
]
datum = df_auswahl.index[-1]
antwort = input(
f"Wollen Sie den Zeitraum eingrenzen? j/n: /n"
f" Erstes Datum ist {datum}"
)
if antwort == "j":
monat = int(input("Geben Sie den Monat ein: "))
tag = int(input("Geben Sie einen Tag ein: "))
datum = pd.Timestamp(year=2020, month=monat, day=tag)
df_plot_auswahl = df_auswahl[df_auswahl.index > datum]
aktuelle_fallzahlen = df_plot_auswahl.iloc[0].astype(int)
aktuelles_datum = aktuelle_fallzahlen.name
stand = Date.today()
plot = df_plot_auswahl.plot(
title=f"Coronafälle Stand: {stand}", grid=True, rot=30, marker="."
)
plt.gcf().autofmt_xdate()
plt.xlabel("Datum")
plt.ylabel("Fälle")
for fallzahl, farbe in zip(
aktuelle_fallzahlen, (line.get_color() for line in plot.get_lines())
):
plt.annotate(
str(fallzahl), xy=(aktuelles_datum, fallzahl), color=farbe
)
plt.show()
plt.savefig(f"{stand} Corona-BW.pdf")
if __name__ == "__main__":
main()