Files
louiscklaw 9035c1312b update,
2025-02-01 02:09:32 +08:00

194 lines
7.8 KiB
Python

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.express as px
from pycountry_convert import country_alpha2_to_country_name, country_name_to_country_alpha2, country_name_to_country_alpha3
from pycountry_convert.convert_country_alpha2_to_continent_code import COUNTRY_ALPHA2_TO_CONTINENT_CODE
from dash.dependencies import Output, Input
from pycountry_convert.country_wikipedia import WIKIPEDIA_COUNTRY_NAME_TO_COUNTRY_ALPHA2
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
text = "For **{0}**, map shows the countries with which it should open its " \
"air corridor basis the **{1}** Strictness Level of Policy. The map also shows the COVID Infection Rate for the countries from which the " \
"flights will operate."
def try_convert(country_name):
try:
return country_name_to_country_alpha3(country_name)
except:
return None
flights_data = pd.read_csv("dataset/merged-airlines.csv")
flights_data['CC'] = flights_data['source_airport_country'].apply(lambda x: try_convert(x))
latlon = pd.read_csv("dataset/latlon.csv", encoding='latin-1')
continent_filter = {}
for country_code, continent in COUNTRY_ALPHA2_TO_CONTINENT_CODE.items():
countries = continent_filter.get(continent, [])
try:
countries.append(country_alpha2_to_country_name(country_code))
except:
continue
continent_filter[continent] = countries
country_options = []
for country, country_code in WIKIPEDIA_COUNTRY_NAME_TO_COUNTRY_ALPHA2.items():
country_options.append({'label': country, 'value': country_code})
app.layout = html.Div([
html.Div([
html.Div([
html.H2('COVID Recovery Dashboard'),
html.H5('Team 162 - DVA Nightwalkers')
], className = 'columns', style = {'textAlign': 'center'})
]),
html.Div([
html.Div([
html.H6("Select Country and Policy", className = "control_label"),
html.P("Filter by Continent", className = "control_label"),
dcc.RadioItems(
id='continent-selector',
options = [
{'label': 'All', 'value': 'all'},
{'label': 'Africa', 'value': 'AF'},
{'label': 'Asia', 'value': 'AS'},
{'label': 'Europe', 'value': 'EU'},
{'label': 'Oceania', 'value': 'OC'},
{'label': 'North America', 'value': 'NA'},
{'label': 'South America', 'value': 'SA'}
],
value = 'all',
className = "dcc_control"
),
html.P("Select the Country", className = "control_label"),
dcc.Dropdown(
id = "country-selector",
options = country_options,
value = "US",
className = "dcc_control"
),
html.P("Select Strictness Level of Policy", className = "control_label"),
dcc.RadioItems(
id = 'strictness',
options = [
{'label': 'Lowest Level of Strictness', 'value': 'low'},
{'label': 'Moderate Level of Strictness', 'value': 'med'},
{'label': 'Highest Level of Strictness', 'value': 'high'}
],
value = 'low',
className = "dcc_control"
),
html.Span("Policy Selected:", className = "control_label"),
html.Span("Moderate", id="policy_selected", className = "control_label"),
html.P(),
html.Div(id="policy-indicator", style = {'padding': '0px 10px 10px 10px'})
], className = "pretty_container four columns"),
html.Div([
html.P(dcc.Markdown(text.format("United States", "Lowest")), id="text"),
html.P(),
dcc.Graph(
id = 'world_map'
)
], className = "pretty_container eight columns", id='rightCol')
], className = "row",),
], id="mainContainer"
)
@app.callback(Output('country-selector', 'options'),
[Input('continent-selector', 'value')])
def continent_filer_options(continent):
if continent == 'all':
return country_options
else:
options = []
countries = continent_filter[continent]
for country in countries:
options.append({
'label': country,
'value': country_name_to_country_alpha2(country)
})
return options
@app.callback([Output('policy-indicator', 'children'), Output('policy_selected', 'children'), Output('policy_selected', 'style')],
[Input('strictness', 'value')])
def policy_indicator(strictness):
policy = {
"low": [
{'label': 'Public Transport', 'value': 'yes'},
{'label': 'Internal Movements', 'value': 'yes'},
{'label': 'Schools', 'value': 'yes'},
{'label': 'Public Events', 'value': 'yes'},
{'label': 'Workplaces', 'value': 'yes'},
{'label': 'Stay at Home', 'value': 'yes'}
],
"med": [
{'label': 'Public Transport', 'value': 'no'},
{'label': 'Internal Movements', 'value': 'yes'},
{'label': 'Schools', 'value': 'no'},
{'label': 'Public Events', 'value': 'no'},
{'label': 'Workplaces', 'value': 'yes'},
{'label': 'Stay at Home', 'value': 'yes'}
],
"high": [
{'label': 'Public Transport', 'value': 'no'},
{'label': 'Internal Movements', 'value': 'no'},
{'label': 'Schools', 'value': 'no'},
{'label': 'Public Events', 'value': 'no'},
{'label': 'Workplaces', 'value': 'no'},
{'label': 'Stay at Home', 'value': 'no'}
]
}
restrictions = policy[strictness]
elements = []
for restriction in restrictions:
elements.append(html.P())
value = restriction['value']
label = restriction['label']
resp = "✔️" if value == "yes" else ""
elements.append(html.Span(resp, className = f"{value}"))
elements.append(html.Span(f" {label}"))
strictness_lbl = {
'high': 'Strict',
'med': 'Moderate',
'low': 'Lenient'
}
color = {
'low': 'green',
'med': 'orange',
'high': 'red'
}
return elements, strictness_lbl[strictness], {'color': color[strictness]}
@app.callback(
[Output('world_map', 'figure'), Output('text', 'children')],
[Input('country-selector', 'value'), Input('strictness', 'value')])
def update_graph(country_code, strictness):
country = country_alpha2_to_country_name(country_code)
dest_lat = latlon.loc[latlon['name'] == country]['latitude'].iloc[0]
dest_lon = latlon.loc[latlon['name'] == country]['longitude'].iloc[0]
dest_flights = flights_data[flights_data['dest_airport_country'] == country]
fig = px.choropleth(dest_flights, locationmode = "ISO-3", locations = 'CC', color = 'flight_capacity', color_continuous_scale="blues", template = 'seaborn')
for val in dest_flights.itertuples():
source = val[1]
try:
lat = latlon.loc[latlon['name'] == source]['latitude'].iloc[0]
lon = latlon.loc[latlon['name'] == source]['longitude'].iloc[0]
fig = fig.add_scattergeo(lat = [lat, dest_lat], lon = [lon, dest_lon], line = dict(width = 1, color = '#1F1F1F'),
mode = 'lines', showlegend = False)
except:
continue
strictness_level = {
'low': "Lowest",
'med': "Moderate",
'high': "Highest"
}[strictness]
return fig, dcc.Markdown(text.format(country, strictness_level))
if __name__ == '__main__':
app.run_server(debug=True, port=7777)