{ "cells": [ { "cell_type": "markdown", "id": "989af075", "metadata": {}, "source": [ "# Assignment 05\n", "\n", "*Due date: 03.05.2023*\n", "\n", "This week's assignment has to be returned **in the form a jupyter notebook**. \n", "Use jupyter notebooks for what they excel at: combining text, code, and figures. Use the markdown format to structure your assignments, and write text when asked to.\n", "\n", "**As explained in the video, I recommend to download this notebook in order to answer the questions directly in it.**\n", "\n", "Don't forget the [instructions](../assignments)!" ] }, { "cell_type": "markdown", "id": "96f54ccf-f072-4e03-8667-c4fc0bd9b844", "metadata": {}, "source": [ "## Introduction: live meteorological data" ] }, { "cell_type": "markdown", "id": "3b4f4169-3fd7-41a3-911f-cc43e8f05ac9", "metadata": {}, "source": [ "The institute website provides raw data from several stations around Innsbruck using a live feed at the following addresses:\n", "- https://acinn-data.uibk.ac.at/innsbruck/3 for the three days data\n", "- https://acinn-data.uibk.ac.at/innsbruck/7 for the seven days data\n", "\n", "The datasets for other stations are available, per analogy:\n", "- https://acinn-data.uibk.ac.at/obergurgl/3\n", "- two other stations are available but we'll have a look at them next time\n", "\n", "The data is shared by ACINN under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/).\n", "\n", "\n", " \n", "\n", "\n", "The data is provided in the [json](https://www.json.org/) format, often used for web applications. Fortunately, this is very easy to read in python. To make your life easier, I have prepared a reading function below. \n", "\n", "It is not important that you understand how it works exactly, but you should understand how to call the function as explained in the examples below." ] }, { "cell_type": "code", "execution_count": 16, "id": "cca4f823-ce78-4ba9-8c8f-9649645d955c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "TestResults(failed=0, attempted=3)" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "def acinn_meteo_data(station=\"innsbruck\", ndays=3):\n", " \"\"\"Parse live meteorological data from the ACINN servers.\n", "\n", " Requires an internet connection!\n", "\n", " Parameters\n", " ----------\n", " station : str\n", " one of \"innsbruck\", \"obergurgl\"\n", " ndays : int\n", " either 3 or 7 days\n", "\n", " Returns\n", " -------\n", " (time, air_temp, wind_speed, wind_dir) :\n", " the meteorological data (python lists)\n", "\n", " Examples\n", " --------\n", " >>> time, air_temp, wind_speed, wind_dir = acinn_meteo_data()\n", " >>> type(time)\n", " \n", " >>> len(time) > 0\n", " True\n", " \"\"\"\n", " from urllib.request import Request, urlopen\n", " from datetime import datetime, timedelta\n", " import json\n", "\n", " url = f'https://acinn-data.uibk.ac.at/{station}/{ndays}'\n", " req = urlopen(Request(url)).read()\n", " # Read the data\n", " data = json.loads(req.decode('utf-8'))\n", "\n", " # Convert the time\n", " time = np.array([datetime(1970, 1, 1) + timedelta(milliseconds=ds) for ds in data['datumsec']])\n", "\n", " # Read the data\n", " wind_speed = np.array(data['ff'])\n", " wind_dir = np.array(data['dd'])\n", " air_temp = np.array(data['tl'])\n", " \n", " # This is for missing data filtering - more on this in the next class\n", " air_temp[air_temp < -99] = np.NaN\n", "\n", " is_finite = np.isfinite(air_temp) & np.isfinite(wind_speed) & np.isfinite(wind_dir)\n", " if np.any(~is_finite):\n", " time = time[is_finite]\n", " air_temp = air_temp[is_finite]\n", " wind_speed = wind_speed[is_finite]\n", " wind_dir = wind_dir[is_finite]\n", "\n", " # Return the data\n", " return time, air_temp, wind_speed, wind_dir\n", "\n", "# Testing\n", "import doctest\n", "doctest.testmod()" ] }, { "cell_type": "markdown", "id": "157b0716-9ae5-4253-ae5c-e590e29cb72a", "metadata": {}, "source": [ "The function can be called as follows:" ] }, { "cell_type": "code", "execution_count": 17, "id": "de665368-8f89-4639-b1cb-6eb1149c274c", "metadata": {}, "outputs": [], "source": [ "time, air_temp, wind_speed, wind_dir = acinn_meteo_data(station='innsbruck', ndays=7)" ] }, { "cell_type": "markdown", "id": "e1bf4f72-a416-4602-8696-e5cabc9804cf", "metadata": {}, "source": [ "## Exercise 1: data exploration" ] }, { "cell_type": "markdown", "id": "e96b6889-377b-496c-9095-3cf43e78dac1", "metadata": {}, "source": [ "Please answer the questions one by one in the cells below. " ] }, { "cell_type": "markdown", "id": "06fa9877-5307-46a1-92ec-f8e9789272ab", "metadata": {}, "source": [ "**What is the dtype of the data stored in the `air_temp`, `wind_speed`, `wind_dir` arrays? And their size? And their shape?**" ] }, { "cell_type": "code", "execution_count": null, "id": "2ae51b20-e3b1-4529-8174-650c2ba8a3b6", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "42908931-fe7e-403f-b170-c0a43e168c16", "metadata": {}, "source": [ "**What is the dtype of the data stored in the time array? Try to ask the following questions:**\n", "```python\n", "print(time.dtype)\n", "print(type(time[0]))\n", "```" ] }, { "cell_type": "code", "execution_count": null, "id": "0243ac2e-a5c3-4fe7-b92d-3b90a5aa109c", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "9c4a48af-2914-4019-8505-531b2984ea2a", "metadata": {}, "source": [ "**What is the time resolution of the data? To answer this question, you can print the two first elements of the time array.**" ] }, { "cell_type": "code", "execution_count": null, "id": "2941771b-f853-4801-af0a-153662c6b896", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "617de7da-7fa2-42bf-963f-ada877c7110a", "metadata": {}, "source": [ "## Exercise 2: plotting" ] }, { "cell_type": "markdown", "id": "642ef672-e09b-48f7-a9fa-b5d3988fcb67", "metadata": {}, "source": [ "**Create a graph of the temperature and wind in Innsbruck over the last 3 days**. Start by noticing that matplotlib understands datetime objects very well, and create a graph which looks approximately like this: [example image](https://github.com/fmaussion/intro_to_programming/blob/master/book/week_05/innsbruck_wind_example.png) (note that your plot can be different with respect to dates, colors, etc. But be careful with the axis labels and legends)." ] }, { "cell_type": "code", "execution_count": null, "id": "b2bff291-f442-45dc-a895-80479c63229b", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "8b1f210a-9eae-47eb-a704-08221a94d947", "metadata": {}, "source": [ "*Note: date formatting on axes is something which is very difficult to do automatically. If you feel like it you can try things like shown on the example below (optional).*\n", "\n", "\n", "```python\n", "# Define the date format\n", "from matplotlib.dates import DateFormatter, HourLocator\n", "ax.xaxis.set_major_locator(HourLocator(byhour=[0, 12]))\n", "ax.xaxis.set_minor_locator(HourLocator())\n", "ax.xaxis.set_major_formatter(DateFormatter(\"%b %d, %HH\"))\n", "fig.autofmt_xdate()\n", "```" ] }, { "cell_type": "markdown", "id": "53971747-ca2d-44b5-a9a6-5f110c93b7d4", "metadata": {}, "source": [ "**Now create a graph of the temperature at Innsbruck and Obergurgl over the last 7 days**. The graph should look approximately like this: [example image](https://github.com/fmaussion/intro_to_programming/blob/master/book/week_05/temp_example.png) (note that your plot can be different with respect to dates, colors, etc. But be careful with the axis labels and legends)." ] }, { "cell_type": "code", "execution_count": null, "id": "1e21bb7d-9ffb-44b2-96c5-fab73eaf371b", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "1840cad7-8630-4273-87f0-bfb5fd9f7e69", "metadata": {}, "source": [ "## Exercise 3: statistics" ] }, { "cell_type": "markdown", "id": "9a139c35-7e8f-43a3-8a85-518816da6204", "metadata": {}, "source": [ "**Compute the average, maximum and minimum temperature in Innsbruck over the past 7 days.**" ] }, { "cell_type": "code", "execution_count": null, "id": "3bed6447-f6e1-4e0d-a839-0230ba039d0e", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "5fbf93fe-c7be-4519-a743-17b9acd8e957", "metadata": {}, "source": [ "**Compute the average, maximum and minimum temperature in Innsbruck over the past 24H. For this, assume that the data has no missing timestamp and that the time resolution is constant (this is sometimes wrong but we don't care here).**" ] }, { "cell_type": "code", "execution_count": null, "id": "cd7b7fd8-de1e-4a48-b17e-8e7e1bdd85c1", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "6374d452-2941-4c51-b27d-22924caab82e", "metadata": {}, "source": [ "**Compute the number of times that the 10m wind speed in Innsbruck was above 5 m/s over the past 7 days. Now convert this number to a percentage over the past 7 days.**" ] }, { "cell_type": "code", "execution_count": null, "id": "5892adfe-4e3b-4061-be95-0266baee5636", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "3a0af4c8-5b20-45cd-8c70-34941cce0f05", "metadata": {}, "source": [ "**Compute the number of times that the air temperature in Innsbruck was between 0°C and 10°C over the past 7 days. Now convert this number to a percentage over the past 7 days.**" ] }, { "cell_type": "code", "execution_count": null, "id": "b9ab882a-82d1-4a60-8873-f5f1ea183914", "metadata": {}, "outputs": [], "source": [ "# your answer here" ] }, { "cell_type": "markdown", "id": "a7d15bdb-aceb-47bf-86c6-8ccee9e4fc96", "metadata": {}, "source": [ "## Bonus: average wind direction" ] }, { "cell_type": "markdown", "id": "2f2b6381-ba45-40e4-98a3-b9e52470f2c1", "metadata": {}, "source": [ "Look at the plot you made about wind direction. Can you think of what problem would occur if you try to compute the average of the wind direction?\n", "\n", "Next week, we will address this problem together - so if you are bored you can start to think about how to solve it already ;-)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.8" } }, "nbformat": 4, "nbformat_minor": 5 }