{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ea7d1a2b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import holidays\n",
    "import glob\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "181190f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "pfad = \"../data/tageswerte_pro_Jahr/*.csv\"\n",
    "\n",
    "dateien = glob.glob(pfad)\n",
    "dfs = []\n",
    "for datei in dateien:\n",
    "    df_temp = pd.read_csv(datei, low_memory=False)\n",
    "    df_temp[\"year\"] = os.path.basename(datei).split(\"_\")[2].split(\".\")[0]\n",
    "    dfs.append(df_temp.astype({\"year\":int}))\n",
    "\n",
    "df = pd.concat(dfs, ignore_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d3f4c318",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "operator_name                  0\n",
      "domain_name                    0\n",
      "domain_id                      0\n",
      "counter_site                   0\n",
      "counter_site_id                0\n",
      "counter_serial              1593\n",
      "longitude                      0\n",
      "latitude                       0\n",
      "timezone                       0\n",
      "iso_timestamp                  0\n",
      "channels_in                26510\n",
      "channels_out               26559\n",
      "channels_unknown          220492\n",
      "channels_all                   0\n",
      "site_temperature           20642\n",
      "site_rain_accumulation     20642\n",
      "site_snow_accumulation     20656\n",
      "year                           0\n",
      "dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 66492 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Daten bereinigen\n",
    "\n",
    "# replace various forms of 'na' with np.nan\n",
    "df = df.replace([\"na\", \"NA\", \"Na\"], np.nan)\n",
    "\n",
    "df_backup = df.copy()\n",
    "print(df.isna().sum())\n",
    "# TODO Find if temp rain and snow values are missing in a pattern or at random\n",
    "# convert numeric values to corresponding dtypes\n",
    "df[\"site_temperature\"] = df[\"site_temperature\"].astype(float)\n",
    "df[\"site_rain_accumulation\"] = df[\"site_rain_accumulation\"].astype(float)\n",
    "df[\"site_snow_accumulation\"] = df[\"site_snow_accumulation\"].astype(float)\n",
    "\n",
    "# Mannheim subset, saved to file\n",
    "df_ma = df[df[\"domain_name\"] == 'Stadt Mannheim']\n",
    "df_ma.to_csv(\"../data/processed/daily_bikes_mannheim.csv\", index=False)\n",
    "#print(df_ma.isna().sum())\n",
    "\n",
    "\n",
    "\n",
    "# Wie ist das verhältnis über den gesammten Zeitraum von Regen und Schnee?\n",
    "\n",
    "\n",
    "labels = [\n",
    "    \"Januar\", \"Februar\", \"März\", \"April\", \"Mai\", \"Juni\",\n",
    "    \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"Dezember\"\n",
    "]\n",
    "df2 = df.copy()\n",
    "\n",
    "\n",
    "df2[\"iso_timestamp\"] = pd.to_datetime(\n",
    "    df2[\"iso_timestamp\"],\n",
    "    errors=\"coerce\", #If 'coerce', then invalid parsing will be set as NaT.\n",
    "    utc=True\n",
    ")\n",
    "\n",
    "df_ma = df2.loc[df2[\"domain_name\"] == \"Stadt Mannheim\"]\n",
    "df_ma = df_ma.dropna(subset=[\"iso_timestamp\"])\n",
    "df_ma[\"month\"] = df_ma[\"iso_timestamp\"].dt.month.astype(int)\n",
    "df_ma[\"site_rain_accumulation\"] = pd.to_numeric(df_ma[\"site_rain_accumulation\"], errors=\"coerce\").clip(lower=0)\n",
    "df_ma[\"site_snow_accumulation\"] = pd.to_numeric(df_ma[\"site_snow_accumulation\"], errors=\"coerce\").clip(lower=0)\n",
    "\n",
    "monthly = (\n",
    "    df_ma.groupby(\"month\")[[\"site_rain_accumulation\", \"site_snow_accumulation\"]]\n",
    "        .sum()\n",
    "        .reindex(range(1, 13), fill_value=0)\n",
    ")\n",
    "\n",
    "rain_sum = monthly[\"site_rain_accumulation\"].to_numpy()\n",
    "snow_sum = monthly[\"site_snow_accumulation\"].to_numpy()\n",
    "\n",
    "x = np.arange(12)\n",
    "width = 0.35\n",
    "fig, ax = plt.subplots()\n",
    "\n",
    "rects1 = ax.bar(x - width/2, rain_sum, width, label=\"Rain\")\n",
    "rects2 = ax.bar(x + width/2, snow_sum, width, label=\"Snow\")\n",
    "\n",
    "ax.set_ylabel(\"Akkumulation\")\n",
    "ax.set_title(\"Monatliche Summe Regen vs. Schnee (Mannheim)\")\n",
    "ax.set_xticks(x, labels, rotation=45, ha=\"right\")\n",
    "ax.legend()\n",
    "\n",
    "ax.bar_label(rects1, padding=3, fmt=\"%.1f\")\n",
    "ax.bar_label(rects2, padding=3, fmt=\"%.1f\")\n",
    "\n",
    "fig.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "\n",
    "# IDEE: Man könnte noch zeigen wie akurat Schnee / Regen sind, in dem man farblich darstellt ob die Temperatur > oder < 0 war."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "eb082a0d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Shorten der Labels für bessere Lesbarkeit im Plot\n",
    "max_length = 15\n",
    "df_ma[\"short_labels\"] = df_ma[\"counter_site\"].apply(lambda x: x[:max_length] + (\"…\" if len(x) > max_length else \"\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ea13a213",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_1603716/1295171260.py:7: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
      "  axs[0].set_yticklabels(range(0,3501, 500))\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 75456 characters]",
      "text/plain": [
       "<Figure size 1500x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "avg_per_year = df_ma.groupby(\"year\")[\"channels_all\"].mean()\n",
    "years = avg_per_year.index.astype(str)\n",
    "fig, axs = plt.subplots(1,2, figsize=(15, 5))\n",
    "\n",
    "sns.barplot(x=years, y=avg_per_year.values, ax=axs[0])\n",
    "axs[1].set_yticks(range(0, 3501, 500))\n",
    "axs[0].set_yticklabels(range(0,3501, 500))\n",
    "axs[0].set_xlabel(\"Year\")\n",
    "axs[0].set_ylabel(\"Average channels_all\")\n",
    "axs[0].set_title(\"Average daily observations per year (Mannheim 2014-2025)\", fontsize=16)\n",
    "\n",
    "\n",
    "# WICHTIG Hier kommt der Abfall des Mittelwerts dadurch, dass mehr Zählstationen hinzugefügt wurden, die nicht an einem Hotspot standen, also Mittelwert sinkt.\n",
    "plot_data = pd.DataFrame({\n",
    "    'Year': years,\n",
    "    'Average': avg_per_year\n",
    "})\n",
    "\n",
    "sns.lineplot(x='Year', y='Average', data=plot_data, marker='o', ax=axs[1])\n",
    "axs[1].set_yticks(range(0, 3501, 500))\n",
    "axs[1].set_yticklabels(range(0,3501, 500))\n",
    "axs[1].set_title(\"Average daily observations (Mannheim 2014-2025)\", fontsize=16)\n",
    "axs[1].set_xlabel(\"Year\", fontsize=12)\n",
    "axs[1].set_ylabel(\"Average Number of bikes\", fontsize=12)\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "cf4ab2b6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 43000 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "y = df_ma.groupby(by=\"year\")[\"counter_site\"].nunique()\n",
    "plt.figure(figsize=(10, 6))\n",
    "sns.lineplot(x=y.index, y=y.values, marker='o')\n",
    "plt.title(\"Number of counting stations per year in Mannheim\", fontsize=16)\n",
    "plt.xlabel(\"Year\", fontsize=12)\n",
    "plt.ylabel(\"Number of stations\", fontsize=12)\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f938cd69",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 28488 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# sollte man das normieren?\n",
    "sum_per_year = df_ma.groupby(\"year\")[\"channels_all\"].sum()\n",
    "\n",
    "sum_per_year = sum_per_year.sort_index()\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "sns.barplot(x=years, y=sum_per_year.values)\n",
    "\n",
    "plt.xlabel(\"Year\")\n",
    "plt.ylabel(\"Total observations in millions\")\n",
    "plt.title(\"Total observations per year (Mannheim)\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2993be48",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 35420 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_ma[\"timestamp\"] = pd.to_datetime(df_ma[\"iso_timestamp\"])\n",
    "df_ma[\"year\"] = df_ma[\"timestamp\"].dt.year\n",
    "df_ma[\"month\"] = df_ma[\"timestamp\"].dt.month\n",
    "df_ma[\"date\"] = df_ma[\"timestamp\"].dt.date\n",
    "\n",
    "df_2024 = df_ma[df_ma[\"year\"] == 2024].copy()\n",
    "\n",
    "monthly_avg_2024 = (df_2024.groupby(\"month\")[\"channels_all\"].mean().reset_index())\n",
    "\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.bar( monthly_avg_2024[\"month\"], monthly_avg_2024[\"channels_all\"], color=\"steelblue\" ) \n",
    "plt.title(\"Average Daily Bike Counts per Month (Mannheim 2024)\") \n",
    "plt.xlabel(\"Month\") \n",
    "plt.ylabel(\"Average daily bike counts\") \n",
    "plt.xticks(range(1, 13)) \n",
    "plt.grid(axis=\"y\", alpha=0.3) \n",
    "plt.tight_layout() \n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "46d1936b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 37008 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_ma[\"timestamp\"] = pd.to_datetime(df_ma[\"iso_timestamp\"])\n",
    "df_ma[\"year\"] = df_ma[\"timestamp\"].dt.year\n",
    "df_ma[\"month\"] = df_ma[\"timestamp\"].dt.month\n",
    "df_ma[\"date\"] = df_ma[\"timestamp\"].dt.date\n",
    "\n",
    "df_2023 = df_ma[df_ma[\"year\"] == 2023].copy()\n",
    "\n",
    "monthly_avg_2023 = (df_2023.groupby(\"month\")[\"channels_all\"].mean().reset_index())\n",
    "\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.bar( monthly_avg_2023[\"month\"], monthly_avg_2023[\"channels_all\"], color=\"steelblue\" ) \n",
    "plt.title(\"Average Daily Bike Counts per Month (Mannheim 2023)\") \n",
    "plt.xlabel(\"Month\") \n",
    "plt.ylabel(\"Average daily bike counts\") \n",
    "plt.xticks(range(1, 13)) \n",
    "plt.grid(axis=\"y\", alpha=0.3) \n",
    "plt.tight_layout() \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "579dfd5b",
   "metadata": {},
   "source": [
    "### Höhere Fahrradzählungen im Jahr 2023: \n",
    "Einfluss der BUGA‑Saison auf den Radverkehr in Mannheim?\n",
    " (14 April bis 8 Oktober)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "69ff22d9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1200x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48476 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_22_23_24 = df_ma[df_ma[\"year\"].isin([2022, 2023,2024])].copy()\n",
    "\n",
    "\n",
    "monthly_sum = (df_22_23_24.groupby([\"year\", \"month\"])[\"channels_all\"].sum().reset_index())\n",
    "monthly_pivot = monthly_sum.pivot(index=\"month\", columns=\"year\", values=\"channels_all\")\n",
    "\n",
    "\n",
    "plt.figure(figsize=(12, 6))\n",
    "monthly_pivot.plot(kind=\"bar\", figsize=(12,6), width=0.8)\n",
    "\n",
    "plt.title(\"Total Monthly Bike Counts in Mannheim (2022 vs. 2023)\")\n",
    "plt.xlabel(\"Month\")\n",
    "plt.ylabel(\"Total bike counts per month\")\n",
    "plt.xticks(range(0,12), range(1,13), rotation=0)\n",
    "plt.grid(axis=\"y\", alpha=0.3)\n",
    "plt.legend(title=\"Year\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5e75d24f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 29604 characters]",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_ma[\"t\"] = pd.to_datetime(df_ma[\"iso_timestamp\"], utc=True).dt.tz_convert(\"Europe/Berlin\")\n",
    "df_ma[\"metric\"] = pd.to_numeric(df_ma[\"channels_all\"], errors=\"coerce\")\n",
    "\n",
    "def buga_sum(y):\n",
    "    start = pd.Timestamp(f\"{y}-04-14\", tz=\"Europe/Berlin\")\n",
    "    end   = pd.Timestamp(f\"{y}-10-08\", tz=\"Europe/Berlin\")\n",
    "    return df_ma.loc[(df_ma[\"t\"] >= start) & (df_ma[\"t\"] <= end), \"metric\"].sum()\n",
    "\n",
    "vals = {y: buga_sum(y) for y in [2022, 2023, 2024]}\n",
    "\n",
    "\n",
    "plt.figure(figsize=(8,5))\n",
    "bars = plt.bar([\"2022\", \"2023 (BUGA)\", \"2024\"], [vals[2022], vals[2023], vals[2024]],)\n",
    "plt.bar_label(bars, padding=3, fmt=\"%.0f\")\n",
    "plt.title(\"Bike Counts During BUGA Period (14 Apr – 8 Oct)\")\n",
    "plt.ylabel(\"Total bike counts\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "a7193c9a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 92436 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_ma[\"year\"] = df_ma[\"t\"].dt.year\n",
    "df_ma[\"month\"] = df_ma[\"t\"].dt.month\n",
    "\n",
    "df_buga = df_ma[df_ma[\"month\"].between(4, 10)]\n",
    "\n",
    "monthly = df_buga.groupby([\"year\", \"month\"])[\"metric\"].sum().reset_index()\n",
    "\n",
    "plt.figure(figsize=(10,6))\n",
    "for y in [2022, 2023, 2024]:\n",
    "    subset = monthly[monthly[\"year\"] == y]\n",
    "    plt.plot(subset[\"month\"], subset[\"metric\"], marker=\"o\", label=str(y))\n",
    "\n",
    "plt.title(\"Monthly Bike Counts (April–October)\")\n",
    "plt.xlabel(\"Month\")\n",
    "plt.ylabel(\"Total bike counts\")\n",
    "plt.xticks(range(4,11))\n",
    "plt.legend()\n",
    "plt.grid(alpha=0.3)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0dc459ff",
   "metadata": {},
   "source": [
    "Im August gehen wohl viele in den Urlaub aber im September hat 2023 deutlich mehr Fahrradzählungen als 2022 und 2024"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "f3c0497b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 72292 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_ma[\"weekday\"] = df_ma[\"t\"].dt.day_name()\n",
    "\n",
    "def buga_period(y):\n",
    "    start = pd.Timestamp(f\"{y}-04-14\", tz=\"Europe/Berlin\")\n",
    "    end   = pd.Timestamp(f\"{y}-10-08\", tz=\"Europe/Berlin\")\n",
    "    return df_ma[(df_ma[\"t\"] >= start) & (df_ma[\"t\"] <= end)]\n",
    "\n",
    "df_buga_2023 = buga_period(2023)\n",
    "df_buga_2022 = buga_period(2022)\n",
    "\n",
    "sns.boxplot(data=pd.concat([df_buga_2022.assign(year=\"2022\"),df_buga_2023.assign(year=\"2023\")]), x=\"weekday\", y=\"metric\", hue=\"year\")\n",
    "plt.xticks(rotation=45)\n",
    "plt.title(\"Weekday Bike Counts During BUGA vs. 2022\")\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "eed0fab8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 21680 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.barplot(df_ma[df_ma[\"counter_site\"] == \"Renzstraße\"],x=\"year\", y=\"channels_all\")\n",
    "# sns.barplot(df_ma[df_ma[\"counter_site\"] == \"Kurpfalzbrücke\"],x=\"year\", y=\"channels_all\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "ab084d8d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 95924 characters]",
      "text/plain": [
       "<Figure size 1000x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "station_sum = df_ma.groupby(\"short_labels\")[\"channels_all\"].sum().sort_values(ascending=False)\n",
    "year_counts = df_ma.groupby(\"short_labels\")[\"year\"].nunique()\n",
    "year_counts = year_counts[station_sum.index]  # Reorder year_counts to match the sorted station_sum\n",
    "\n",
    "plt.figure(figsize=(10, 7))\n",
    "sns.barplot(x=station_sum.index, y=station_sum.values, hue=year_counts)\n",
    "plt.xticks(rotation=75)\n",
    "plt.xlabel(\"Station\")\n",
    "plt.ylabel(\"Total observations (2014-2024) in millions\")\n",
    "plt.title(\"Total observations per station (Mannheim)\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4a88437",
   "metadata": {},
   "source": [
    "### Größtes Radverkehrsaufkommen nach Städten\n",
    "\n",
    "Da die Zählstellen zu unterschiedlichen Zeitpunkten in Betrieb genommen wurden, wurde für vergleichende Analysen ein gemeinsamer Beobachtungszeitraum definiert. Hierzu wurde für jede Zählstelle das erste Jahr mit verfügbaren Messdaten bestimmt. In der Analyse wurden ausschließlich Zählstellen berücksichtigt, die spätestens ab dem Jahr 2018 Daten aufweisen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "65437931",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 29500 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 91676 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "station_coverage = (\n",
    "    df.groupby(\"counter_site\")\n",
    "      .agg(\n",
    "          first_year=(\"year\", \"min\"),\n",
    "          last_year=(\"year\", \"max\"),\n",
    "          n_observations=(\"year\", \"count\")\n",
    "      )\n",
    "      .reset_index()\n",
    ")\n",
    "\n",
    "station_coverage.sort_values(\"first_year\")\n",
    "valid_stations = station_coverage[\n",
    "    station_coverage[\"first_year\"] <= 2018\n",
    "][\"counter_site\"]\n",
    "\n",
    "df_common = df[\n",
    "    (df[\"counter_site\"].isin(valid_stations)) &\n",
    "    (df[\"year\"] >= 2018)\n",
    "]\n",
    "plt.figure(figsize=(10, 6))\n",
    "sns.histplot(station_coverage[\"first_year\"], bins=range(2013, 2026))\n",
    "plt.xlabel(\"Startjahr der Zählstelle\")\n",
    "plt.ylabel(\"Anzahl der Zählstellen\")\n",
    "plt.title(\"Jährlicher Zuwachs der Fahrradzählstellen in BaWü\")\n",
    "plt.show()\n",
    "\n",
    "# Top 10 Zählstellen\n",
    "avg_df_common = (\n",
    "    df_common.groupby([\"counter_site\", \"domain_name\"], as_index=False)\n",
    "      .agg(avg_daily_counts=(\"channels_all\", \"mean\"))\n",
    ")\n",
    "\n",
    "# Top 10 Zählstellen basierend auf dem durchschnittlichen täglichen Fahrradverkehr\n",
    "top10_common = avg_df_common.sort_values(\"avg_daily_counts\", ascending=False).head(10)\n",
    "\n",
    "# Visualisierung der Top 10 Zählstellen\n",
    "plt.figure(figsize=(15, 6))\n",
    "sns.barplot(\n",
    "    data=top10_common,\n",
    "    y=\"counter_site\",\n",
    "    x=\"avg_daily_counts\",\n",
    "    hue=\"domain_name\"\n",
    ")\n",
    "\n",
    "plt.ylabel(\"Zählstelle\")\n",
    "plt.xlabel(\"Durchschnittliche Fahrradfahrten pro Tag\")\n",
    "plt.title(\"Top 10 Zählstellen mit dem höchsten durchschnittlichen Fahrradverkehr\\n(2018 und später)\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "d239120a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO welche Station hat den größten Messwertsprung innerhalb eines Jahres erlebt -> woran lag das"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "ad8639cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Kurpfalzbrücke', 'Renzstraße', 'Konrad-Adenauer…', 'Jungbuschbrücke', 'Schlosspark Lin…', 'Neckarauer Über…']\n",
      "6\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 70124 characters]",
      "text/plain": [
       "<Figure size 2000x1000 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Renzstraße - Höchster Wert:\n",
      "date            2018-04-10\n",
      "channels_all          7638\n",
      "Name: 239807, dtype: object\n",
      "Kurpfalzbrücke - Höchster Wert:\n",
      "date            2018-04-10\n",
      "channels_all         10558\n",
      "Name: 245866, dtype: object\n",
      "am 11.04.2018 gab es in Mannheim einen Warnstreik im öffentlichen Dienst und mehrere tausend Menschen nahmen an Demonstrationen teil.\n",
      "Das erklärt die Ausreißer bei den Fahrradzählungen an diesem Tag.\n"
     ]
    }
   ],
   "source": [
    "max_length = 15\n",
    "\n",
    "top5 = station_sum[:6]                 # oder besser: station_sum.head(5)\n",
    "top5_names = top5.index.tolist()\n",
    "print(top5_names)\n",
    "\n",
    "mask_top5 = df_ma[\"short_labels\"].isin(top5_names)\n",
    "df_ma_top = df_ma[mask_top5]\n",
    "\n",
    "print(df_ma_top[\"counter_site\"].nunique())\n",
    "plt.figure(figsize=(20, 10))\n",
    "sns.boxplot(data=df_ma_top, notch=True, x=\"short_labels\", y=\"channels_all\")\n",
    "plt.xticks(rotation=0)\n",
    "plt.ylabel(\"Fahrradpassagen\")\n",
    "plt.xlabel(\"Stationen\")\n",
    "plt.title(\"Tägliche Beobachtungen der sechs beliebtesten Stationen in Mannheim (Stadt Mannheim - 2014-2024)\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "df[\"timestamp\"] = pd.to_datetime(df_ma[\"iso_timestamp\"])\n",
    "#Renzstraße\n",
    "renz = df_ma[df_ma[\"counter_site\"] == \"Renzstraße\"]\n",
    "renz_max = renz.loc[renz[\"channels_all\"].idxmax()]\n",
    "print(\"Renzstraße - Höchster Wert:\")\n",
    "print(renz_max[[\"date\", \"channels_all\"]])\n",
    "\n",
    "#Kurpfalzbrücke\n",
    "kurp = df_ma[df_ma[\"counter_site\"] == \"Kurpfalzbrücke\"]\n",
    "kurp_max = kurp.loc[kurp[\"channels_all\"].idxmax()]\n",
    "print(\"Kurpfalzbrücke - Höchster Wert:\")\n",
    "print(kurp_max[[\"date\", \"channels_all\"]])      \n",
    "\n",
    "print(\"am 11.04.2018 gab es in Mannheim einen Warnstreik im öffentlichen Dienst und mehrere tausend Menschen nahmen an Demonstrationen teil.\")\n",
    "print(\"Das erklärt die Ausreißer bei den Fahrradzählungen an diesem Tag.\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "de88a7d7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 1223252 characters]",
      "text/plain": [
       "<Figure size 1579.86x1500 with 42 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_ma['day_of_week'] = df_ma['timestamp'].dt.dayofweek  # 0=Monday, 6=Sunday\n",
    "df_ma['month'] = df_ma['timestamp'].dt.month\n",
    "df_ma['is_weekend'] = df_ma['day_of_week'].isin([5, 6]).astype(int)  # 1 if weekend, 0 if weekday\n",
    "# You can manually add holidays or use a library like `holidays` to check if the day is a public holiday.\n",
    "de_holidays = holidays.Germany(years=2023)  # For Germany, for example\n",
    "df_ma['is_holiday'] = df_ma['timestamp'].dt.date.isin(de_holidays.keys()).astype(int)\n",
    "\n",
    "\n",
    "variables = ['day_of_week','month','is_weekend', 'is_holiday', 'channels_all', 'site_temperature', 'site_rain_accumulation']\n",
    "\n",
    "# Create the scatterplot matrix using Seaborn's pairplot\n",
    "sns.pairplot(df_ma[variables], diag_kind='kde', plot_kws={'alpha': 0.5, 's': 50}, hue=\"is_holiday\")\n",
    "\n",
    "# Customize the plot\n",
    "plt.suptitle('Matrix Scatterplot of Bike Counting Data', fontsize=16)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "121023cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# is_weekend und channels_all vergleichen\n",
    "sum_weekdays = sum(df_ma[df_ma[\"is_weekend\"]==0][\"channels_all\"])\n",
    "sum_weekends = sum(df_ma[df_ma[\"is_weekend\"]==1][\"channels_all\"])\n",
    "num_weekdays = len(df_ma[df_ma[\"is_weekend\"]==0])# Since each row is an hour, divide by 24 to get the number of days\n",
    "num_weekends = len(df_ma[df_ma[\"is_weekend\"]==1])  \n",
    "avg_weekdays = sum_weekdays / num_weekdays\n",
    "avg_weekends = sum_weekends / num_weekends\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e6c3493",
   "metadata": {},
   "source": [
    "# Korrelation zwischen Temperatur und Fahrradnutzung"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "95626fa7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 216212 characters]",
      "text/plain": [
       "<Figure size 1500x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Pearson: 0.202\n",
      "Spearman: 0.223\n",
      "Pearson: 0.195\n",
      "Spearman: 0.272\n"
     ]
    }
   ],
   "source": [
    "fig, axs = plt.subplots(1,2,figsize=(15, 5))\n",
    "sns.scatterplot(data=df_ma, y=\"site_rain_accumulation\", x=\"channels_all\", ax=axs[0])\n",
    "sns.regplot(data=df_ma, x=\"site_rain_accumulation\", y=\"channels_all\",scatter_kws={'s': 10}, line_kws={'color': 'red'}, ax=axs[1])\n",
    "plt.xlabel(\"Site temperature\")\n",
    "plt.ylabel(\"Bike counts\") \n",
    "axs[0].set_title(\"Temperature vs. bicycle counts (Stadt Mannheim)\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "# Pearson\n",
    "pearson_ma = df_ma[[\"channels_all\", \"site_temperature\"]].corr(method=\"pearson\").loc[\"channels_all\", \"site_temperature\"]\n",
    "\n",
    "# Spearman\n",
    "spearman_ma = df_ma[[\"channels_all\", \"site_temperature\"]].corr(method=\"spearman\").loc[\"channels_all\", \"site_temperature\"]\n",
    "\n",
    "print(f\"Pearson: {pearson_ma:.3f}\")\n",
    "print(f\"Spearman: {spearman_ma:.3f}\")\n",
    "\n",
    "# Drop all nan values in site_temperature from big dataframe\n",
    "df[\"site_temperature\"] = df[\"site_temperature\"].replace([\"na\", \"NA\", \"Na\"], np.nan)\n",
    "df = df.dropna(subset=[\"site_temperature\"])\n",
    "pearson_all = df[[\"channels_all\", \"site_temperature\"]].corr(method=\"pearson\").loc[\"channels_all\", \"site_temperature\"]\n",
    "spearman_all = df[[\"channels_all\", \"site_temperature\"]].corr(method=\"spearman\").loc[\"channels_all\", \"site_temperature\"]\n",
    "\n",
    "print(f\"Pearson: {pearson_all:.3f}\")\n",
    "print(f\"Spearman: {spearman_all:.3f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fe1513a",
   "metadata": {},
   "source": [
    "#### Die insgesamte Korrelation zwischen der Temperatur und der Fahrradnutzung in Mannheim beträgt nach Pearson 0.202.\n",
    "#### Betrachtet man jedoch die Korrelation der einzelnen der Messstationen so ergeben sich folgende Werte."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46404807",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                                       counter_site  pearson_corr\n",
      "1                                      B38. RI. AUS      0.011942\n",
      "15                             Lindenhofüberführung      0.235979\n",
      "25                    Theodor-Heuss-Anlage. RI. AUS      0.393459\n",
      "21                                       Renzstraße      0.445103\n",
      "19           Neckarauer Übergang -Schwetzinger Str.      0.486533\n",
      "5                    Feudenheimerstr. stadteinwärts      0.510540\n",
      "27                    Theodor-Heuss-Anlage. RI. IN.      0.510875\n",
      "7                      Feudenheimstr. stadtauswärts      0.533080\n",
      "13                                   Kurpfalzbrücke      0.548310\n",
      "9                                   Jungbuschbrücke      0.557844\n",
      "11                           Konrad-Adenauer-Brücke      0.568114\n",
      "17                                    Luzenbergstr.      0.584917\n",
      "3                                    Fernmeldeturm.      0.619432\n",
      "23  Schlosspark Lindenhof (Richtung Jugendherberge)      0.629848\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 78648 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "corr_per_station = (\n",
    "    df_ma.groupby(\"counter_site\")[[\"channels_all\", \"site_temperature\"]]\n",
    "         .corr(method=\"pearson\")\n",
    "         .reset_index()\n",
    ")\n",
    "\n",
    "# Nur die Zeilen channels_all vs. site_temperature extrahieren\n",
    "corr_per_station = corr_per_station[\n",
    "    (corr_per_station[\"level_1\"] == \"site_temperature\") &\n",
    "    (corr_per_station[\"counter_site\"].notna())\n",
    "][[\"counter_site\", \"channels_all\"]].rename(columns={\"channels_all\": \"pearson_corr\"})\n",
    "\n",
    "print(corr_per_station.sort_values(\"pearson_corr\"))\n",
    "\n",
    "corr_per_station_sorted = corr_per_station.sort_values(\"pearson_corr\")\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.barh(corr_per_station_sorted[\"counter_site\"], corr_per_station_sorted[\"pearson_corr\"])\n",
    "plt.xlabel(\"Pearson correlation (site_temperature vs. channels_all)\")\n",
    "plt.ylabel(\"Station\")\n",
    "plt.title(\"Correlation between temperature and bicycle counts by station\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "faf7f222",
   "metadata": {},
   "source": [
    "An den meisten Stationen ist die Korrelation positiv (d.h. wärmere Tage → mehr Radverkehr).“\n",
    "„Die Stärke variiert jedoch deutlich zwischen den Stationen (von ~0 bis ~0.63).“\n",
    "„Insbesondere an Stationen X, Y, Z ist der Zusammenhang besonders stark.“"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "56606822",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_1589771/3267416270.py:14: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.violinplot( data=df_ma, x=\"rain_category\", y=\"channels_all\",palette=\"Blues\", legend = False, ax=axs[1])\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 180624 characters]",
      "text/plain": [
       "<Figure size 1500x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Spearman (Mannheim): -0.100\n",
      "Spearman (alle Städte): -0.114\n"
     ]
    }
   ],
   "source": [
    "#rain category\n",
    "df_ma[\"rain_category\"] = pd.cut(df_ma[\"site_rain_accumulation\"], bins=[-0.1, 0, 2.5, 7.6, 50], labels=[\"No Rain\", \"Light Rain\", \"Moderate Rain\", \"Heavy Rain\"]) \n",
    "\n",
    "fig, axs = plt.subplots(1,2,figsize=(15, 5))\n",
    "\n",
    "\n",
    "sns.regplot(data=df_ma, y=\"site_rain_accumulation\", x=\"channels_all\",scatter_kws={'s': 10, 'alpha':0.5}, line_kws={'color': 'red'}, ax=axs[0])\n",
    "\n",
    "plt.xlabel(\"rain accumulation\")\n",
    "plt.ylabel(\"bike counts\") \n",
    "axs[0].set_title(\"rain vs. bicycle counts (Stadt Mannheim)\")\n",
    "plt.tight_layout()\n",
    "\n",
    "sns.violinplot( data=df_ma, x=\"rain_category\", y=\"channels_all\",palette=\"Blues\", legend = False, ax=axs[1]) \n",
    "axs[1].set_title(\"Bike counts by rain category\") \n",
    "axs[1].set_xlabel(\"Rain category\") \n",
    "axs[1].set_ylabel(\"Bike counts\") \n",
    "axs[1].grid(axis=\"y\", alpha=0.3)\n",
    "plt.tight_layout() \n",
    "plt.show()\n",
    "\n",
    "# Spearman\n",
    "spearman_ma = ( df_ma[[\"channels_all\", \"site_rain_accumulation\"]] .corr(method=\"spearman\") .loc[\"channels_all\", \"site_rain_accumulation\"] ) \n",
    "print(f\"Spearman (Mannheim): {spearman_ma:.3f}\") \n",
    "# Gesamtdaten bereinigen \n",
    "df[\"site_rain_accumulation\"] = df[\"site_rain_accumulation\"].replace([\"na\", \"NA\", \"Na\"], np.nan) \n",
    "df = df.dropna(subset=[\"site_rain_accumulation\"]) \n",
    "spearman_all = ( df[[\"channels_all\", \"site_rain_accumulation\"]].corr(method=\"spearman\").loc[\"channels_all\", \"site_rain_accumulation\"] ) \n",
    "print(f\"Spearman (alle Städte): {spearman_all:.3f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "80a7ede1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{2020: np.int64(1688124), 2021: np.int64(1525185), 2022: np.int64(1789267), 2023: np.int64(2262742)} 2022 vs 2021 %: 17.31475198090724 2022 vs 2023 %: -20.924833675248877\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 29220 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Auswirkung df_maer Einführung df_maes 9-Euro-Tickets vom 1. Juni 2022 bis zum 31. August 2022 im Vergleich zum Jahr df_maavor undf_ma df_maanach\n",
    "\n",
    "#In Mannheim\n",
    "\n",
    "df_ma[\"t\"] = pd.to_datetime(df_ma[\"iso_timestamp\"].astype(str).str.strip(), errors=\"coerce\", utc=True)\n",
    "df_ma = df_ma.dropna(subset=[\"t\"])\n",
    "\n",
    "\n",
    "df_ma[\"metric\"] = pd.to_numeric(df_ma[\"channels_all\"], errors=\"coerce\") \n",
    "\n",
    "def win_sum(y):\n",
    "    a = pd.Timestamp(f\"{y}-06-01\", tz=\"Europe/Berlin\")\n",
    "    b = pd.Timestamp(f\"{y}-09-01\", tz=\"Europe/Berlin\")\n",
    "    return df_ma.loc[(df_ma[\"t\"]>=a) & (df_ma[\"t\"]<b), \"metric\"].sum(skipna=True)\n",
    "\n",
    "vals = {y: win_sum(y) for y in [2020, 2021, 2022, 2023]}\n",
    "print(vals, \"2022 vs 2021 %:\", (vals[2022]/vals[2021]-1)*100, \"2022 vs 2023 %:\", (vals[2022]/vals[2023]-1)*100)\n",
    "\n",
    "fig, ax = plt.subplots()\n",
    "bars = ax.bar([\"2020\", \"2021\",\"2022 (9€)\",\"2023\"], [vals[2020], vals[2021], vals[2022], vals[2023]])\n",
    "ax.bar_label(bars, padding=3, fmt=\"%.0f\")\n",
    "ax.set_title(\"Mannheim: Juni–Aug Vergleich 2021/2022/2023\")\n",
    "ax.set_ylabel(\"Summe channels_all\")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "47cc2917",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 80460 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Monatliche Beobachtungen im Jahr 2021, 2022, 2023 in Mannheim als Liniendiagramm\n",
    "\n",
    "years  = [2021, 2022, 2023]\n",
    "labels = [\"Jan\",\"Feb\",\"Mär\",\"Apr\",\"Mai\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Okt\",\"Nov\",\"Dez\"]\n",
    "\n",
    "# --- 1) vorbereiten + filtern ---\n",
    "d = df_backup.copy()\n",
    "d[\"t\"] = (pd.to_datetime(d[\"iso_timestamp\"], errors=\"coerce\", utc=True)\n",
    "            .dt.tz_convert(\"Europe/Berlin\"))\n",
    "d = d[\n",
    "    (d[\"domain_name\"].astype(str).str.strip() == \"Stadt Mannheim\") &\n",
    "    (d[\"counter_site\"].astype(str).str.strip() == \"Kurpfalzbrücke\") &\n",
    "    d[\"t\"].notna()\n",
    "]\n",
    "d[\"metric\"] = pd.to_numeric(d[\"channels_all\"], errors=\"coerce\").fillna(0)\n",
    "\n",
    "# --- 2) Tageswerte -> Monatssummen je Jahr ---\n",
    "daily = d.groupby(d[\"t\"].dt.floor(\"D\"))[\"metric\"].sum().reset_index(name=\"metric\")\n",
    "daily[\"year\"]  = daily[\"t\"].dt.year\n",
    "daily[\"month\"] = daily[\"t\"].dt.month\n",
    "daily = daily[daily[\"year\"].isin(years)]\n",
    "\n",
    "m = daily.groupby([\"year\", \"month\"])[\"metric\"].sum().reset_index(name=\"month_sum\")\n",
    "\n",
    "# Pivot für Plot (Monate 1..12 als Index, Jahre als Spalten)\n",
    "sum_pivot = (m.pivot(index=\"month\", columns=\"year\", values=\"month_sum\")\n",
    "               .reindex(range(1, 13), fill_value=0))\n",
    "\n",
    "\n",
    "daily = d.groupby(d[\"t\"].dt.floor(\"D\"))[\"metric\"].sum().reset_index(name=\"metric\")\n",
    "daily[\"year\"]  = daily[\"t\"].dt.year\n",
    "daily[\"month\"] = daily[\"t\"].dt.month\n",
    "daily = daily[daily[\"year\"].isin(years)]\n",
    "\n",
    "daily[\"is_holiday\"] = False\n",
    "\n",
    "m = (daily.groupby([\"year\",\"month\"])\n",
    "          .agg(month_sum=(\"metric\",\"sum\"),\n",
    "               holiday_share=(\"is_holiday\",\"mean\"))  # Anteil Ferientage im Monat\n",
    "          .reset_index())\n",
    "\n",
    "sum_pivot = (m.pivot(index=\"month\", columns=\"year\", values=\"month_sum\")\n",
    "               .reindex(range(1,13), fill_value=0))\n",
    "hol_pivot = (m.pivot(index=\"month\", columns=\"year\", values=\"holiday_share\")\n",
    "               .reindex(range(1,13), fill_value=0))\n",
    "\n",
    "\n",
    "x = np.arange(1, 13)\n",
    "fig, ax = plt.subplots()\n",
    "\n",
    "for y in years:\n",
    "    ax.plot(x, sum_pivot[y].to_numpy(), label=str(y))\n",
    "\n",
    "\n",
    "ax.set_xticks(x, labels)\n",
    "ax.set_xlabel(\"Monat\")\n",
    "ax.set_ylabel(\"Summe channels_all\")\n",
    "ax.set_title(\"Mannheim: Monatssumme + Ferienanteil\")\n",
    "ax.legend()\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "# Prognose berechnen für Wachstum im Jahr 2022 mit bezug ob das 9$ Ticket gedämpft hat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d892782",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Städte mit Messstationen ab 2015:\n",
      " \n",
      "['König-Karls-Brücke Barometer', 'Wiwilibrücke', 'Thedor-Heuss-Brücke Querschnitt', 'Neckarufer', 'Erbprinzenstraße', 'Barometer Kirchheim u. Teck', 'Untere Hartmattenstraße / Hauptfriedhof', 'Kurpfalzbrücke', 'Unterführung Steinlach/Karlstraße Südseite - Steinlachallee']\n",
      "28366\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='year', ylabel='channels_all'>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 70320 characters]",
      "text/plain": [
       "<Figure size 2000x1000 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "grouped_df = df_backup.groupby(\"domain_name\")\n",
    "print(\"Städte mit Messstationen ab 2015:\\n \")\n",
    "biggest_stations = []\n",
    "for name, group in grouped_df:\n",
    "    first_year = min(group[\"year\"])\n",
    "    if first_year <= 2014:\n",
    "        # city has station with first year before 2015\n",
    "        # print(group[\"domain_name\"].iloc[0])\n",
    "        means_2015 = group.groupby(\"counter_site\")[\"channels_all\"].mean()\n",
    "        \n",
    "        biggest_station_in_city = means_2015.idxmax()\n",
    "        biggest_stations.append(biggest_station_in_city)\n",
    "        \n",
    "print(biggest_stations)\n",
    "df_with_biggest = df[df[\"counter_site\"].isin(biggest_stations)]\n",
    "print(len(df_with_biggest))\n",
    "# remove entries from before 2015\n",
    "df_with_biggest_after_2015 = df_with_biggest[df_with_biggest[\"year\"]>=2015]\n",
    "len(df_with_biggest_after_2015)\n",
    "fig = plt.figure(figsize=(20, 10))\n",
    "\n",
    "sns.barplot(df_with_biggest_after_2015, x=\"year\", y=\"channels_all\", hue=\"counter_site\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13aeefb6",
   "metadata": {},
   "source": [
    "# Poster\n",
    "### Einleitung\n",
    "Der Radverkehr gewinnt als umweltfreundliche und flächeneffiziente Verkehrsform in Städten zunehmend an Bedeutung. Um Infrastruktur und Mobilitätsangebote bedarfsgerecht planen zu können, werden in Baden-Württemberg an zahlreichen Standorten automatische Fahrradzählstationen betrieben. Im Rahmen einer explorativen Datenanalyse werten wir Zähldaten aus mehreren Städten in Baden-Württemberg aus, mit einem besonderen Fokus auf die Stadt Mannheim. Die Analyse umfasst sowohl Tageszählwerte über den Zeitraum von 2014 bis 2024 als auch stündliche Zählwerte für ausgewählte Mannheimer Stationen. Ergänzend stehen wetterbezogene Variablen wie Temperatur, Regen- und Schneehöhe zur Verfügung. Ziel ist es, zeitliche Muster und Trends im Fahrradverkehrsaufkommen zu identifizieren. Sowohl im Tagesverlauf (z.B. Berufsverkehrsspitzen) als auch über die Jahre hinweg und den Einfluss von Standortunterschieden und Witterung auf das gemessene Radverkehrsaufkommen besser zu verstehen.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee13f17d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ausgewählte Stationen (Top 5 Städte): ['Wiwilibrücke', 'Unterführung Steinlach/Karlstraße Südseite - Steinlachallee', 'Plöck', 'Erbprinzenstraße', 'Renzstraße']\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_1589771/3805953305.py:43: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df_with_biggest_after_2015[\"counter_site_short\"] = df_with_biggest_after_2015[\"counter_site\"]\n",
      "/tmp/ipykernel_1589771/3805953305.py:49: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df_with_biggest_after_2015[\"city_station\"] = (\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 289936 characters]",
      "text/plain": [
       "<Figure size 2000x1000 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 1. Sicherstellen, dass wir mit df_backup arbeiten\n",
    "df = df_backup.copy()\n",
    "\n",
    "grouped_df = df.groupby(\"domain_name\")\n",
    "\n",
    "city_best_station = []  # (city, best_station, mean_2015)\n",
    "\n",
    "for city, city_df in grouped_df:\n",
    "    # Hat die Stadt eine Station vor 2015?\n",
    "    first_year_in_city = city_df[\"year\"].min()\n",
    "    if first_year_in_city > 2014:\n",
    "        continue\n",
    "\n",
    "    city_2015 = city_df[city_df[\"year\"] == 2015]\n",
    "    if city_2015.empty:\n",
    "        continue\n",
    "\n",
    "    means_2015 = city_2015.groupby(\"counter_site\")[\"channels_all\"].mean()\n",
    "    best_station = means_2015.idxmax()\n",
    "    best_mean_2015 = means_2015.max()\n",
    "\n",
    "    city_best_station.append((city, best_station, best_mean_2015))\n",
    "\n",
    "# 2. Nach mean_2015 sortieren und Top 5 nehmen\n",
    "city_best_station_sorted = sorted(\n",
    "    city_best_station,\n",
    "    key=lambda x: x[2],  # sortiere nach best_mean_2015\n",
    "    reverse=True\n",
    ")\n",
    "\n",
    "top5 = city_best_station_sorted[:5]\n",
    "\n",
    "# 3. Nur Stationen der Top-5-Städte\n",
    "biggest_stations = [entry[1] for entry in top5]\n",
    "print(\"Ausgewählte Stationen (Top 5 Städte):\", biggest_stations)\n",
    "\n",
    "# 4. DataFrame nur mit diesen Stationen\n",
    "df_with_biggest = df[df[\"counter_site\"].isin(biggest_stations)]\n",
    "\n",
    "# 5. Nur Jahre ab 2015\n",
    "df_with_biggest_after_2015 = df_with_biggest[df_with_biggest[\"year\"] >= 2015]\n",
    "\n",
    "df_with_biggest_after_2015[\"counter_site_short\"] = df_with_biggest_after_2015[\"counter_site\"]\n",
    "\n",
    "df_with_biggest_after_2015.loc[\n",
    "    df_with_biggest_after_2015[\"counter_site\"] == \"Unterführung Steinlach/Karlstraße Südseite - Steinlachallee\",\n",
    "    \"counter_site_short\"\n",
    "] = \"Unterführung Steinlachallee\"\n",
    "df_with_biggest_after_2015[\"city_station\"] = (\n",
    "    df_with_biggest_after_2015[\"domain_name\"] + \" – \" + df_with_biggest_after_2015[\"counter_site_short\"]\n",
    ")\n",
    "\n",
    "# 6. Plot\n",
    "plt.figure(figsize=(20, 10))\n",
    "ax = sns.lineplot(\n",
    "    data=df_with_biggest_after_2015,\n",
    "    x=\"year\",\n",
    "    y=\"channels_all\",\n",
    "    hue=\"city_station\",\n",
    ")\n",
    "ax.set_ylabel(\"Fahrradpassagen\", fontsize=14)\n",
    "ax.set_xlabel(\"Jahr\", fontsize=14)\n",
    "legend = ax.legend(\n",
    "    title=\"Stadt mit Stationsname\"\n",
    ")\n",
    "ax.tick_params(labelsize=12)\n",
    "\n",
    "ax.set_title(\n",
    "    \"Verlauf der gezählten Fahrradpassagen ab 2015 – Top-5-Städte (größte Zählstation je Stadt)\",\n",
    "    fontsize=16\n",
    ")\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "dat (3.12.3)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
