{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Analyse des vergangenen Sommers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dieses Notebook kann lokal oder **direkt im Browser** auf [](https://mybinder.org/v2/gh/meteotest/urban-heat-API-docs/data-analysis?labpath=python_data_analysis_past_summer.ipynb) oder [](https://colab.research.google.com/github/meteotest/urban-heat-API-docs/blob/data-analysis/python_data_analysis_past_summer.ipynb) ausgeführt werden." ] }, { "cell_type": "code", "execution_count": 119, "metadata": { "ExecuteTime": { "end_time": "2024-07-04T14:26:00.401223Z", "start_time": "2024-07-04T14:25:57.249309Z" } }, "outputs": [], "source": [ "import requests \n", "import pandas as pd\n", "import geopandas as gpd \n", "import matplotlib.pyplot as plt # for plotting\n", "import folium\n", "import branca\n", "import math" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Einschlaftemperatur Karte" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Auswahl an Zeitraum (z.B. eine Hitzewelle, ein Monat, oder der ganze Sommer)\n", "# Daten (UTC) als String in folgendem Format: \"YYYY-MM-DDThh:mm:ssZ\"\n", "time_from = \"2024-10-01T22:00:00Z\"\n", "time_to = \"2024-10-31T22:00:00Z\"\n", "\n", "# Auswahl an Stationen\n", "# Wenn alle Stationen berücksichtigt werden sollen, dann einfach die Liste leer lassen\n", "# Hier ist eine Liste aller Stationen mit Name und ID: https://smart-urban-heat-map.ch/api/v2/latest\n", "# station_ids = [\"11001\", \"11002\"] # Beispiel für nur eine Auswahl von zwei Stationen\n", "station_ids = [] # Beispiel für alle Stationen" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2024-07-04T14:26:00.409675Z", "start_time": "2024-07-04T14:26:00.402497Z" } }, "outputs": [], "source": [ "def get_stations() -> gpd.GeoDataFrame:\n", " response = requests.get(\n", " url=f\"https://smart-urban-heat-map.ch/api/v2/latest\"\n", " )\n", " stations = gpd.read_file(response.text)\n", "\n", " # calculate only at subset of stations \n", " # (if a subset was defined, otherwise take all stations)\n", " if station_ids:\n", " stations = stations[stations[\"stationId\"].isin(station_ids)]\n", " \n", " return stations\n", "\n", "def get_station_sleep_temp_analysis(time_from: str, time_to: str) -> pd.DataFrame:\n", " stations = get_stations()\n", "\n", " # check that time series are at least 83 % complete\n", " time_from_dt = pd.to_datetime(time_from)\n", " time_to_dt = pd.to_datetime(time_to)\n", " time_difference = time_to_dt - time_from_dt\n", " expected_values = round(time_difference.days * 24 * 2)\n", " \n", " stations['einschlaftemperatur'] = None\n", "\n", " for idx, station in stations.iterrows():\n", " station_id = station.stationId\n", " response = requests.get(url=f\"https://smart-urban-heat-map.ch/api/v2/timeseries?stationId={station_id}&timeFrom={time_from}&timeTo={time_to}\")\n", " \n", " payload = response.json()\n", "\n", " if payload[\"values\"] is None or not len(payload[\"values\"]): \n", " stations = stations.drop(idx)\n", " continue\n", " \n", " if len(payload[\"values\"]) < expected_values:\n", " stations = stations.drop(idx)\n", " continue\n", " \n", " df = pd.DataFrame(payload[\"values\"])\n", "\n", " df[\"dateObserved\"] = pd.to_datetime(df[\"dateObserved\"])\n", " df[\"dateObserved\"] = df[\"dateObserved\"].dt.tz_convert(\"Europe/Zurich\")\n", " \n", " # hier werden die Hitzetage und Tropennächte berechnet\n", " einschlaftemperatur = calc_einschlaftemperatur(df)\n", " \n", " stations.loc[idx, 'einschlaftemperatur'] = einschlaftemperatur\n", "\n", " return stations\n", "\n", "def calc_einschlaftemperatur(df: pd.DataFrame) -> float:\n", " sleep_time_mask = (df['dateObserved'].dt.hour >= 22) & (df['dateObserved'].dt.hour < 23)\n", " sleep_time = df.loc[sleep_time_mask]\n", "\n", " nightly_sleep_temperatures = (\n", " sleep_time.groupby(sleep_time['dateObserved'].dt.date)['temperature'].mean()\n", " )\n", "\n", " return nightly_sleep_temperatures.mean()" ] }, { "cell_type": "code", "execution_count": 122, "metadata": { "ExecuteTime": { "end_time": "2024-07-04T14:32:06.529897Z", "start_time": "2024-07-04T14:26:03.289556Z" } }, "outputs": [ { "data": { "text/html": [ "
| \n", " | name | \n", "stationId | \n", "geometry | \n", "einschlaftemperatur | \n", "
|---|---|---|---|---|
| 0 | \n", "Ausserholligen 2, ewb | \n", "11001 | \n", "POINT (7.40642 46.94542) | \n", "21.239814 | \n", "
| 1 | \n", "Bundesplatz | \n", "11002 | \n", "POINT (7.44353 46.94692) | \n", "22.099029 | \n", "
| 2 | \n", "Breitenrain, Waffenweg | \n", "11003 | \n", "POINT (7.45192 46.96173) | \n", "21.727543 | \n", "
| 3 | \n", "Schosshaldenfriedhof 2 | \n", "11004 | \n", "POINT (7.47186 46.95339) | \n", "20.17552 | \n", "
| 4 | \n", "Monbijou-Park | \n", "11005 | \n", "POINT (7.43462 46.94187) | \n", "20.943326 | \n", "
| ... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
| 134 | \n", "Monopoliplatz Lyss | \n", "12006 | \n", "POINT (7.30588 47.07661) | \n", "21.617444 | \n", "
| 135 | \n", "Spielplatz Stiglimatt | \n", "12007 | \n", "POINT (7.2992 47.07154) | \n", "20.998686 | \n", "
| 136 | \n", "Sportanlage Grien | \n", "12008 | \n", "POINT (7.29574 47.07508) | \n", "20.725683 | \n", "
| 138 | \n", "Reitplatz Grünau | \n", "12010 | \n", "POINT (7.30167 47.07714) | \n", "20.846787 | \n", "
| 139 | \n", "Sigriswil | \n", "13001 | \n", "POINT (7.71244 46.71345) | \n", "20.11358 | \n", "
113 rows × 4 columns
\n", "| \n", " | name | \n", "stationId | \n", "geometry | \n", "uhi | \n", "
|---|---|---|---|---|
| 1 | \n", "Bundesplatz | \n", "11002 | \n", "POINT (7.44353 46.94692) | \n", "uhi\n", "0 1.372617\n", "1 1.285352\n", "2 1.2579... | \n", "
| 9 | \n", "Bümpliz Stöckacker | \n", "11010 | \n", "POINT (7.39587 46.94302) | \n", "uhi\n", "0 0.343092\n", "1 0.389947\n", "2 0.4306... | \n", "
| 17 | \n", "Breitenrainplatz 127 | \n", "11019 | \n", "POINT (7.45403 46.95825) | \n", "uhi\n", "0 1.017292\n", "1 1.022750\n", "2 1.0620... | \n", "
| 87 | \n", "Köniz Blinzernplateau Strom-/Telefonmast | \n", "11090 | \n", "POINT (7.42771 46.92253) | \n", "uhi\n", "0 1.159601\n", "1 1.166302\n", "2 1.2812... | \n", "
| 95 | \n", "Ostermundigen Schermenweg | \n", "11098 | \n", "POINT (7.48036 46.95778) | \n", "uhi\n", "0 0.447994\n", "1 0.485579\n", "2 0.5590... | \n", "
| 97 | \n", "Umland Bolligen | \n", "11100 | \n", "POINT (7.50376 46.96681) | \n", "uhi\n", "0 -1.181658\n", "1 -1.239773\n", "2 -1.2348... | \n", "
| 118 | \n", "Zollikofen Zentrum Laterne | \n", "11121 | \n", "POINT (7.45693 46.99266) | \n", "uhi\n", "0 1.404620\n", "1 1.419536\n", "2 1.4175... | \n", "