diff --git a/App-Covid_weekly_infectious_cases.ipynb b/App-Covid_weekly_infectious_cases.ipynb new file mode 100644 index 0000000..6aceb32 --- /dev/null +++ b/App-Covid_weekly_infectious_cases.ipynb @@ -0,0 +1,575 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "2b8d4789-78b3-4f31-9207-4ba6fcf90ad4", + "metadata": {}, + "outputs": [], + "source": [ + "# data = \"data/data-3d9Ex.csv\"\n", + "import plotly.express as px\n", + "import pandas as pd\n", + "import geopandas as gpd\n", + "import numpy as np\n", + "import json\n", + "import datetime as dt\n", + "\n", + "from dash import Dash, dcc, html, Input, Output\n", + "import dash_bootstrap_components as dbc\n", + "import os\n", + "\n", + "colorscales = px.colors.named_colorscales()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1b985925-91c8-4eb9-bb41-293318bd924e", + "metadata": {}, + "outputs": [], + "source": [ + "## Local settings to be able to test the app in the user environment and for running as a report\n", + "URL_PREFIX = os.path.join(\"/\", os.getenv(\"REPORT_URL\"))\n", + "PORT = os.getenv(\"REPORT_PORT\", 9000)\n", + "HOSTNAME = os.getenv(\"HOSTNAME\")\n", + "SERVER_NAME = os.getenv(\"SERVERNAME\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "9ef312bf-3c18-4417-806b-3d07830d96d3", + "metadata": {}, + "outputs": [], + "source": [ + "# Hungary counties shapefile\n", + "# url = \"https://maps.princeton.edu/download/file/stanford-dt251rh6351-shapefile.zip\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c6822dbd-d897-445f-9743-f7267d66537c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "#!cd data && wget https://maps.princeton.edu/download/file/stanford-dt251rh6351-shapefile.zip && unzip stanford-dt251rh6351-shapefile.zip" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "57706225-be2f-4267-9333-60d3e736f854", + "metadata": {}, + "outputs": [], + "source": [ + "# read shp data into geopandas\n", + "gg = gpd.read_file(\"data/dt251rh6351.shp\")\n", + "ggjson = gg.to_json()\n", + "# gg.head()\n", + "\n", + "# We will need gejson\n", + "dggjson = json.loads(ggjson)\n", + "\n", + "# Turns out one of the county's name is misspelled so we rename it for now in the dataframe\n", + "# [f['properties']['name_1'] for f in dggjson['features']]" + ] + }, + { + "cell_type": "markdown", + "id": "bb6b0eda-51f1-4bf9-b161-487db05e4ebc", + "metadata": {}, + "source": [ + "## Heti adatok" + ] + }, + { + "cell_type": "markdown", + "id": "770e6ba1-e48a-4fde-aa77-5b898e9853e5", + "metadata": {}, + "source": [ + "### Letoltes\n", + "https://atlo.team/koronaterkep/#megyeibovebb" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7e5eeb9f-847c-4e73-8b73-9fc6a97ba56b", + "metadata": {}, + "outputs": [], + "source": [ + "# https://www.eea.europa.eu/data-and-maps/data/eea-reference-grids-2/gis-files/hungary-shapefile\n", + "# Fertozottek szama kumulativ\n", + "url = \"https://docs.google.com/spreadsheets/d/1djH-yUHLPwuEExCjiXS__6-8W2Yp_msFvShpL4bBcuM/export?format=xlsx&gid=1283792994\"\n", + "# heti uj esetek szama\n", + "url = \"https://docs.google.com/spreadsheets/d/1djH-yUHLPwuEExCjiXS__6-8W2Yp_msFvShpL4bBcuM/export?format=xlsx&gid=1332599659\"\n", + "heti_df = pd.read_excel(url) \n", + "\n", + "heti_df['date'] = pd.to_datetime(heti_df['Dátum']) #, format='%y-%m-%d')\n", + "#heti_df = heti_df.drop(columns=['Dátum', 'Összesen'])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "4290d58d-5dfc-46ee-afd7-c46148c62e7c", + "metadata": {}, + "outputs": [], + "source": [ + "#Rename Győr to Gyor\n", + "heti_df = heti_df.rename(columns={'Győr-Moson-Sopron':'Gyor-Moson-Sopron'})" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "e6d276b1-ccf5-4248-bd08-9c27c180fac7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
13141516171819202122...146147148149150151152153154155
Bács-Kiskun19.03.01.00.00.00.01.00.00.00.0...577.0505.00.0730.0217.0216.0184.0177.0184.0197.0
Baranya23.06.04.00.03.00.00.00.00.01.0...658.0537.00.0661.0257.0204.0182.0193.0232.0354.0
Békés8.03.02.01.02.01.0-6.00.00.00.0...585.0359.00.0507.0208.0199.0228.0204.0239.0226.0
Borsod-Abaúj-Zemplén7.038.08.09.03.0-1.00.0-3.00.01.0...658.0495.00.0575.0179.0174.0158.0174.0195.0205.0
Budapest317.0386.0299.0284.0198.0103.094.0103.064.058.0...1819.01437.00.01977.0835.0786.0795.01011.01171.01042.0
\n", + "

5 rows × 143 columns

\n", + "
" + ], + "text/plain": [ + " 13 14 15 16 17 18 19 20 \\\n", + "Bács-Kiskun 19.0 3.0 1.0 0.0 0.0 0.0 1.0 0.0 \n", + "Baranya 23.0 6.0 4.0 0.0 3.0 0.0 0.0 0.0 \n", + "Békés 8.0 3.0 2.0 1.0 2.0 1.0 -6.0 0.0 \n", + "Borsod-Abaúj-Zemplén 7.0 38.0 8.0 9.0 3.0 -1.0 0.0 -3.0 \n", + "Budapest 317.0 386.0 299.0 284.0 198.0 103.0 94.0 103.0 \n", + "\n", + " 21 22 ... 146 147 148 149 150 \\\n", + "Bács-Kiskun 0.0 0.0 ... 577.0 505.0 0.0 730.0 217.0 \n", + "Baranya 0.0 1.0 ... 658.0 537.0 0.0 661.0 257.0 \n", + "Békés 0.0 0.0 ... 585.0 359.0 0.0 507.0 208.0 \n", + "Borsod-Abaúj-Zemplén 0.0 1.0 ... 658.0 495.0 0.0 575.0 179.0 \n", + "Budapest 64.0 58.0 ... 1819.0 1437.0 0.0 1977.0 835.0 \n", + "\n", + " 151 152 153 154 155 \n", + "Bács-Kiskun 216.0 184.0 177.0 184.0 197.0 \n", + "Baranya 204.0 182.0 193.0 232.0 354.0 \n", + "Békés 199.0 228.0 204.0 239.0 226.0 \n", + "Borsod-Abaúj-Zemplén 174.0 158.0 174.0 195.0 205.0 \n", + "Budapest 786.0 795.0 1011.0 1171.0 1042.0 \n", + "\n", + "[5 rows x 143 columns]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "heti_df.set_index('date', inplace=True)\n", + "\n", + "heti_df = heti_df.resample('7D').sum()\n", + "\n", + "heti_df.index=range(13,13+len(heti_df.index))\n", + "heti_df = heti_df.transpose()\n", + "heti_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "d50af1bc-b8d4-4fee-9992-f9939071945b", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_723/3451946974.py:2: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", + "\n", + " cc = gg.centroid\n" + ] + } + ], + "source": [ + "# Get the mean of the county's centroids\n", + "cc = gg.centroid\n", + "\n", + "clon = cc.apply(lambda x: x.x).mean()\n", + "clat = cc.apply(lambda x: x.y).mean()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "ea3d30f8-1e5e-48bd-831e-cc4ec1cffac4", + "metadata": {}, + "outputs": [], + "source": [ + "heti_df.index=heti_df.index.rename('name_1')\n", + "\n", + "heti_df=heti_df.reset_index()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "92cc4cef-e3dd-4197-b0d7-74c2fff04a42", + "metadata": {}, + "outputs": [], + "source": [ + "colorscale = [[0, 'rgb(166,206,227, 0.5)'],\n", + " [0.01, 'rgb(31,120,180,0.5)'],\n", + " [0.05, 'rgb(178,223,138,0.5)'],\n", + " [0.1, 'rgb(51,160,44,0.5)'],\n", + " [0.15, 'rgb(251,154,153,0.5)'],\n", + " [1, 'rgb(227,26,28,0.5)']\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "3665a994-ec8a-4d7f-ae5c-69955fac559b", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_723/344204418.py:1: FutureWarning: Dropping of nuisance columns in DataFrame reductions (with 'numeric_only=None') is deprecated; in a future version this will raise TypeError. Select only valid columns before calling the reduction.\n", + " maxinfect = heti_df.max(axis=1).max()\n" + ] + } + ], + "source": [ + "maxinfect = heti_df.max(axis=1).max()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "7c319fee-1e1b-4b8a-bea0-690b5e3d67d3", + "metadata": {}, + "outputs": [], + "source": [ + "filtered_df = heti_df[['name_1', heti_df.columns[1]]]\n", + "# filtered_df=filtered_df.rename(columns={heti_df.index[0]:'sum'})\n", + "fig = px.choropleth_mapbox(filtered_df, geojson=dggjson, locations='name_1', color=heti_df.columns[1],\n", + " color_continuous_scale= colorscale,\n", + " #locationmode='geojson-id',\n", + " featureidkey='properties.name_1',\n", + " range_color=(0, maxinfect),\n", + " mapbox_style=\"carto-positron\",\n", + " zoom=5.7, center = {\"lat\": clat, \"lon\": clon},\n", + " opacity=0.5,\n", + " labels={heti_df.columns[1]:'Megfertozodesek szama'}\n", + " )\n", + "fig.update_layout(margin={\"r\":0,\"t\":0,\"l\":0,\"b\":0});\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "bfc17416-a94b-47fb-8166-ef8ae4e111ed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'k8plex-krft.vo.elte.hu'" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "SERVER_NAME=SERVER_NAME[1:]\n", + "SERVER_NAME" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "427ebf00-b4e8-44de-b3a6-e8ab150c3bf2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You can access your report at k8plex-krft.vo.elte.hu//notebook/test/wfct0p-jupyter\n", + "Dash is running on http://wfct0p-jupyter:9000/notebook/test/wfct0p-jupyter/\n", + "\n", + " * Serving Flask app \"__main__\" (lazy loading)\n", + " * Environment: production\n", + "\u001b[31m WARNING: This is a development server. Do not use it in a production deployment.\u001b[0m\n", + "\u001b[2m Use a production WSGI server instead.\u001b[0m\n", + " * Debug mode: off\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " * Running on http://wfct0p-jupyter:9000/ (Press CTRL+C to quit)\n", + "157.181.172.118 - - [09/Feb/2023 23:23:57] \"GET /notebook/test/wfct0p-jupyter/ HTTP/1.1\" 200 -\n", + "157.181.172.118 - - [09/Feb/2023 23:23:58] \"GET /notebook/test/wfct0p-jupyter/_dash-dependencies HTTP/1.1\" 200 -\n", + "157.181.172.118 - - [09/Feb/2023 23:23:58] \"GET /notebook/test/wfct0p-jupyter/_dash-layout HTTP/1.1\" 200 -\n", + "157.181.172.118 - - [09/Feb/2023 23:23:59] \"GET /notebook/test/wfct0p-jupyter/_dash-component-suites/dash/dcc/async-graph.js HTTP/1.1\" 200 -\n", + "157.181.172.118 - - [09/Feb/2023 23:23:59] \"GET /notebook/test/wfct0p-jupyter/_dash-component-suites/dash/dcc/async-slider.js HTTP/1.1\" 304 -\n", + "157.181.172.118 - - [09/Feb/2023 23:23:59] \"GET /notebook/test/wfct0p-jupyter/_dash-component-suites/dash/dcc/async-plotlyjs.js HTTP/1.1\" 304 -\n", + "157.181.172.118 - - [09/Feb/2023 23:24:00] \"POST /notebook/test/wfct0p-jupyter/_dash-update-component HTTP/1.1\" 200 -\n", + "157.181.172.118 - - [09/Feb/2023 23:24:04] \"POST /notebook/test/wfct0p-jupyter/_dash-update-component HTTP/1.1\" 200 -\n" + ] + } + ], + "source": [ + "print(\"You can access your report at %s/%s\"%(SERVER_NAME, URL_PREFIX))\n", + "\n", + "external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']\n", + "app = Dash(__name__, external_stylesheets=[dbc.themes.SANDSTONE], url_base_pathname=URL_PREFIX+\"/\")\n", + "\n", + "app.layout = html.Div([\n", + " html.H4(\"Az azonosított fertőzöttek száma megyénként\"),\n", + "\n", + " dcc.Graph(id=\"graph\", figure=fig),\n", + " # dcc.Slider(heti_df.index[0], heti_df.index[-1], marks={i:i for i in range(heti_df.index[0], heti_df.index[-1],5)},\n", + " # value=heti_df.index[0],\n", + " # id='my-slider'\n", + " # ),\n", + " dcc.Slider(heti_df.columns[1], heti_df.columns[-1], marks={i:i for i in range(heti_df.columns[1], heti_df.columns[-1],5)},\n", + " value=heti_df.columns[1],\n", + " id='my-slider'\n", + " ),\n", + "\n", + "])\n", + "\n", + "@app.callback(\n", + " Output(\"graph\", \"figure\"), \n", + " Input('my-slider', 'value'))\n", + "\n", + "def update_figure(selected_week):\n", + " \n", + " filtered_df = heti_df[['name_1', selected_week]]\n", + " #filtered_df=filtered_df.reset_index().rename(columns={selected_week:'sum','index':'name_1'})\n", + "\n", + " #filtered_df = heti_df[['name_1', heti_df.columns[1]]]\n", + " # filtered_df=filtered_df.rename(columns={heti_df.index[0]:'sum'})\n", + " fig = px.choropleth_mapbox(filtered_df, geojson=dggjson, locations='name_1', color=selected_week,\n", + " color_continuous_scale=colorscale,\n", + " #locationmode='geojson-id',\n", + " \n", + "\n", + " featureidkey='properties.name_1',\n", + " range_color=(0, maxinfect),\n", + " mapbox_style=\"carto-positron\",\n", + " zoom=5.7, center = {\"lat\": clat, \"lon\": clon},\n", + " opacity=0.5,\n", + " labels={selected_week:'Megfertozodesek szama'}\n", + " )\n", + " fig.update_layout(margin={\"r\":0,\"t\":0,\"l\":0,\"b\":0}, transition_duration=500)\n", + "\n", + " return fig\n", + "\n", + "app.run_server(debug=False, port=PORT, host=HOSTNAME)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "273cfd77-ca2f-4a06-aead-bdf013a44b34", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}