From 92482fff0717b8761368772710fd091480c80dfd Mon Sep 17 00:00:00 2001 From: toravest Date: Mon, 24 Mar 2025 11:25:58 +0100 Subject: [PATCH] add statistic historical data, rewrite functions for universal use --- notebooks/statistic_data_notebook.ipynb | 180 ++++++++++++++++++++++++ src/my_package/fetch_data.py | 46 +----- src/my_package/write_data.py | 4 +- src/my_package/year_data.py | 38 +++++ 4 files changed, 226 insertions(+), 42 deletions(-) create mode 100644 notebooks/statistic_data_notebook.ipynb create mode 100644 src/my_package/year_data.py diff --git a/notebooks/statistic_data_notebook.ipynb b/notebooks/statistic_data_notebook.ipynb new file mode 100644 index 0000000..e4b10d1 --- /dev/null +++ b/notebooks/statistic_data_notebook.ipynb @@ -0,0 +1,180 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Velg et sted i Norge å få statistisk data\n", + "\n", + "Denne API-en henter statistisk historisk data, herunder, statistisk data basert på de historiske dataene, ikke reele statistisk historisk. \n", + "\n", + "Statistikken er basert på de historiske datane total sett, ikke for hvert år." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import os\n", + "\n", + "# Gets the absolute path to the src folder\n", + "sys.path.append(os.path.abspath(\"../src\"))\n", + "\n", + "# Now we can import the fucntion from the module\n", + "from my_package.year_data import fetch_data\n", + "\n", + "# User input the city, for the weather\n", + "city_name = input(\"Enter a city in Norway: \")\n", + "\n", + "data, folder = fetch_data(city_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Lagre data i json-fil\n", + "\n", + "Skriv inn navn for til filen du vil lagre med dataen.\n", + "\n", + "Eks. test\n", + "Da vil filen lagres som data_**test**.json, i mappen \"../data/output_statistikk/data_{filnavn}.json\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Gets the absolute path to the src folder\n", + "sys.path.append(os.path.abspath(\"../src\"))\n", + "\n", + "from my_package.write_data import write_data\n", + "\n", + "filename = input(\"Write filename: \")\n", + "\n", + "write_data(data, folder, filename)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Lese fra fil\n", + "\n", + "Henter opp data lagret i filen, lagd over, og skriver ut lesbart ved hjelp av pandas" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "\n", + "data = pd.read_json(f'../data/output_statistikk/data_{filename}.json')\n", + "\n", + "display(data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "\n", + "if 'result' in data:\n", + " df = pd.json_normalize(data['result'])\n", + "\n", + " display(df)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plotter data\n", + "Denne koden plotter data basert på gjennomsnitts temperatur gjennom året. For å sikre lagring av de ulike kjøringene, vil grafen bli lagret i mappen \"../data/output_fig/mean_temp_plot_{city_name}.json\"\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import matplotlib.dates as mdates\n", + "import os\n", + "\n", + "output_folder = \"../data/output_fig\"\n", + "os.makedirs(output_folder, exist_ok=True) # Create the folder if it doesn't exist\n", + "\n", + "# Converts to and make a new column with celsius temp, and not kelvin\n", + "df['temp.mean_celsius'] = df['temp.mean'] - 273.15\n", + "temp = df['temp.mean_celsius']\n", + "\n", + "# Convert from day and month, to datetime\n", + "# df['date'] = pd.to_datetime(df[['month', 'day']].assign(year=2024))\n", + "\n", + "# Create a new column that concatenates month and day (e.g., \"03-01\" for March 1)\n", + "df['month_day'] = df[['month', 'day']].apply(lambda x: f\"{x['month']:02d}-{x['day']:02d}\",axis=1)\n", + "\n", + "# Plot the graph of the mean temperature\n", + "plt.figure(figsize=(12, 6))\n", + "plt.plot(df['month_day'], temp)\n", + "\n", + "# Label for easier reading and understanding of the plot\n", + "plt.title(f\"Mean temp - statistic historical {city_name}\")\n", + "plt.xlabel(\"Date\")\n", + "plt.ylabel(\"Temperature (°C)\")\n", + "\n", + "# Customize the x-axis to show ticks and labels only at the start of each month\n", + "plt.gca().xaxis.set_major_locator(mdates.MonthLocator()) \n", + "# Format ticks to show abbreviated month names (e.g., Jan, Feb)\n", + "plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b')) \n", + "\n", + "plt.xticks(rotation=45)\n", + "plt.yticks(range(-20, 30, 2))\n", + "plt.tight_layout()\n", + "plt.grid()\n", + "\n", + "# Save the plot to the data/output_fig folder\n", + "plot_path = os.path.join(output_folder, f\"mean_temp_plot_{city_name}.png\")\n", + "plt.savefig(plot_path) # Save the plot as a PNG file\n", + "\n", + "# Show the plot\n", + "plt.show()\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/my_package/fetch_data.py b/src/my_package/fetch_data.py index a3097ef..f087d28 100644 --- a/src/my_package/fetch_data.py +++ b/src/my_package/fetch_data.py @@ -3,23 +3,17 @@ import os from dotenv import load_dotenv - -# # only for change unix to date for plot -# import matplotlib.pyplot as plt -# import datetime -# import time - load_dotenv() # Gets the key, from my env file API_KEY = os.getenv("API_KEY") # city_name = "Trondheim" -country_code = "NO" +# country_code = "NO" # Temporarily standard times -start_date = 1735686000 -end_date = 1740009323 +# start_date = 1735686000 +# end_date = 1740009323 # Gets the data from the API - openweathermap.org def fetch_data(start_date, end_date, city_name): @@ -36,39 +30,11 @@ def fetch_data(start_date, end_date, city_name): # Converts the data into json data = response.json() + folder = "../data/output_stedsnavn" print("Data fetch: ok") - return data + return data, folder else: # If html status code != 200, print the status code - print("Failed to fetch data from API. Status code:", response.status_code) - - -# myData = fetch_data(start_date, end_date, city_name) - -# if myData is not None: -# # Empty dict for temperature -# temperature = {} -# # Iterates through myData dict, and add the dt (unix_time) and temp to temperature dict -# if "list" in myData: -# for item in myData["list"]: -# if "main" in item and "temp" in item["main"]: -# temperature[item["dt"]] = (item["main"]["temp"]) - -# # print(temperature) - -# x_temp = [datetime.datetime.fromtimestamp(ts) for ts in temperature.keys()] -# # A test plot, to get a visual look of the data -# # x_temp = list(temperature.keys()) -# y_temp = list(temperature.values()) - -# plt.plot(x_temp, y_temp) -# plt.xlabel('Unix Time') -# plt.ylabel('Temperature (°C)') -# plt.title('Temperature over Time') -# plt.grid() -# plt.show() - -# else: -# print("No data to process.") \ No newline at end of file + print(f"Failed to fetch data for {city_name} from API. Status code:", response.status_code) diff --git a/src/my_package/write_data.py b/src/my_package/write_data.py index 233bb91..e46eb2a 100644 --- a/src/my_package/write_data.py +++ b/src/my_package/write_data.py @@ -1,11 +1,11 @@ import json import os -def write_data(data, filename): +def write_data(data, folder, filename): # Ensure the 'output_stedsdata' folder exists inside the 'data' folder at the root of the project script_dir = os.path.dirname(os.path.abspath(__file__)) # Get the directory of the script project_root = os.path.abspath(os.path.join(script_dir, os.pardir, os.pardir)) # Navigate to the root of the project - data_dir = os.path.join(project_root, 'data', 'output_stedsdata') + data_dir = os.path.join(project_root, 'data', folder) os.makedirs(data_dir, exist_ok=True) # Creates 'data/output_stedsdata' folder if it doesn't exist # Write the JSON data to a file inside the 'output_stedsdata' folder diff --git a/src/my_package/year_data.py b/src/my_package/year_data.py new file mode 100644 index 0000000..3d6f780 --- /dev/null +++ b/src/my_package/year_data.py @@ -0,0 +1,38 @@ +# Import of needed libaries +import requests +import os +from dotenv import load_dotenv + + +load_dotenv() + +# Gets the key, from my env file +API_KEY = os.getenv("API_KEY") + +# city_name = "Maura" + +# Gets the data from the API - openweathermap.org +def fetch_data(city_name): + + + # f-string url, to add the "custom" variables to the API-request + url = f"https://history.openweathermap.org/data/2.5/aggregated/year?q={city_name},NO&appid={API_KEY}&units=metric" + + # Saves the API-request for the url + response = requests.get(url) + + # Checks if the status code is OK + if response.status_code == 200: + + # Converts the data into json + data = response.json() + folder = "../data/output_statistikk" + + print("Data fetch: ok") + return data, folder + + else: + # If html status code != 200, print the status code + print(f"Failed to fetch data for city: {city_name} from API. Status code:", response.status_code) + +# myData = fetch_data(city_name) \ No newline at end of file