ALERTAS HIDROLÓGICAS A NIVEL NACIONAL
Select chart from list:
Subzona Hidrográfica
Área Hidrográfica
Zona Hidrográfica
Cambios Alertas
Select chart from list:
Generar grafico
packages = ["matplotlib", "pandas","folium","bokeh","panel","numpy"]
import datetime import json import folium from folium.features import GeoJsonTooltip from bokeh.models import ColumnDataSource from bokeh.plotting import figure import panel as pn import pandas as pd import numpy as np import matplotlib import matplotlib.font_manager from matplotlib.ticker import MaxNLocator from matplotlib.offsetbox import AnchoredText import matplotlib.pyplot as plt from js import document from pyodide import create_proxy from pyodide.http import open_url from branca.colormap import StepColormap def alertas_df(fig,date): df_alertas = pd.DataFrame(columns = ["NOM", "Niveles bajos", "Amarilla","Naranja","Roja"]) fecha = date.strftime("%Y-%m-%d %H:00:00") if alertas['GMT-5'].isin([fecha]).any(): data = alertas.loc[alertas['GMT-5'] == fecha] data = data.transpose() data = data.reset_index(level=0) data = data.set_axis(['id','alerta'],axis='columns') if fig == "area": tipo = areas pos = 1 elif fig == "zona": tipo = zonas pos = 2 for id in tipo: name = tipo[id] b = len(data[data["id"].astype(str).str[:pos].isin([str(id)]) & data["alerta"].isin(["-1"])]) a = len(data[data["id"].astype(str).str[:pos].isin([str(id)]) & data["alerta"].isin(["1"])]) n = len(data[data["id"].astype(str).str[:pos].isin([str(id)]) & data["alerta"].isin(["2"])]) r = len(data[data["id"].astype(str).str[:pos].isin([str(id)]) & data["alerta"].isin(["3"])]) new_row = pd.Series({"NOM": name, "Niveles bajos": b, "Amarilla": a, "Naranja": n, "Roja": r}) df_alertas = pd.concat([df_alertas, new_row.to_frame().T], ignore_index=True) df_alertas = df_alertas.set_index('NOM') if fig == "zona": df_alertas = df_alertas.drop(df_alertas[(df_alertas['Niveles bajos'] == 0) & (df_alertas['Amarilla'] == 0) & (df_alertas['Naranja'] == 0) & (df_alertas['Roja'] == 0)].index) return df_alertas def plot_alertas(fig,date): df_alertas = alertas_df(fig,date) if len(df_alertas) == 0: fig = 'SIN DATOS' else: fecha = date.strftime("%Y-%m-%d %H:00") if fig == "area": titulo = "ALERTAS HIDROLÓGICAS A NIVEL NACIONAL \n Clasificadas por área hidrográfica \n Fecha de actualización: " + fecha size=(6,6) elif fig == "zona": titulo = "ALERTAS HIDROLÓGICAS A NIVEL NACIONAL \n Clasificadas por zona hidrográfica \n Fecha de actualización: " + fecha size=(6,6) ax = df_alertas.plot( kind = 'barh', title = titulo, color = colores, figsize=size, ylabel='Número de alertas', width=0.9, ) ax.xaxis.set_major_locator(MaxNLocator(integer = True)) ax.set_xlabel("Número de Alertas", color="black", labelpad=5) ax.set_ylabel("Área Hidrográfica", color="black", labelpad=5) ax.tick_params(axis="y", labelcolor="black", rotation = 0) ax.tick_params(axis="x", labelcolor="black", rotation = 0) ax.legend(title='Tipo de alerta:', loc='best',fontsize='small') for c in ax.containers: labels = [a if a else "" for a in c.datavalues] ax.bar_label(c, labels=labels) fig = ax.get_figure() plt.tight_layout() display(fig, target="fig") def plot_subzona(date): fecha = date.strftime("%Y-%m-%d %H:00:00") if alertas['GMT-5'].isin([fecha]).any(): data = alertas.loc[alertas['GMT-5'] == fecha] data = data.transpose() data = data.reset_index(level=0) data = data.set_axis(['id','alerta'],axis='columns') b = len(data[data["alerta"].isin(["-1"])]) a = len(data[data["alerta"].isin(["1"])]) n = len(data[data["alerta"].isin(["2"])]) r = len(data[data["alerta"].isin(["3"])]) data = [b,a,n,r] text = f"Niveles bajos : {b}\nAmarilla : {a}\nNaranja : {n}\nRoja : {r}\n\nTOTAL : {b+a+n+r}" fig, ax = plt.subplots(figsize=(6, 6)) ax.set_title(f"ALERTAS HIDROLÓGICAS A NIVEL NACIONAL\nClasificadas por subzonas hidrográficas\nFecha de actualización: {fecha}") ax.pie(data, wedgeprops=dict(width=0.4,linewidth=7,edgecolor="white"), colors=colores,autopct=lambda x: '{:.1f}%'.format(x) if x > 0 else '',pctdistance=0.8) anchored_text = AnchoredText(text, loc=10,borderpad=0.,frameon=False,prop=dict( horizontalalignment='center')) ax.add_artist(anchored_text) else: fig = 'SIN DATOS' display(fig, target="fig") def plot_cambios(date): df_cambios = pd.DataFrame(columns = ["nom_szh","cambio"]) fecha = date.strftime("%Y-%m-%d %H:00:00") if alertas['GMT-5'].isin([fecha]).any(): if fecha == last_str: pass else: data = alertas.loc[(alertas['GMT-5'] == fecha) | (alertas['GMT-5'] == last_str)] data = data.transpose() data = data.reset_index(level=0) data = data.set_axis(['id','old','last'],axis='columns') data = data.drop(0) data = data.astype(int) for id,old,last in zip(data['id'],data['old'],data['last']): if last == old: continue if last == -1 and old != -1: cambio = 'PASO A NIVELES BAJOS' if last == 0 and old != 0: cambio = 'PASO A CONDICIONES NORMALES' if last == 1 and (old == 0 or old == -1): cambio = 'SUBIÓ A ALERTA AMARILLA' if last == 2 and (old == 1 or old == 0 or old == -1): cambio = 'SUBIÓ A ALERTA NARANJA' if last == 3 and old != 3: cambio = 'SUBIÓ A ALERTA ROJA' if last == 2 and old == 3: cambio = 'BAJÓ A ALERTA NARANJA' if last == 1 and (old == 3 or old == 2): cambio = 'BAJÓ A ALERTA AMARILLA' nom_szh = (subzonas[subzonas["id"].isin([id])])['nombre'].values[0] new_row = pd.Series({"nom_szh": nom_szh, "cambio": cambio}) df_cambios= pd.concat([df_cambios, new_row.to_frame().T], ignore_index=True) if len(df_cambios) == 0: arr_cambios = np.array([['',''],['SIN CAMBIOS','SIN CAMBIOS']]) else: df_cambios = df_cambios.groupby(by='cambio')['nom_szh'].apply(list).reset_index() arr_cambios = np.empty((0,2)) for cambio,nom_szh in zip(df_cambios['cambio'],df_cambios['nom_szh']): x = [''] * (len(nom_szh) + 1) x[1] = cambio nom_szh.insert(0,'') z = np.column_stack((x, nom_szh)) arr_cambios = np.append(arr_cambios, z, axis=0) if (0.19278254662030184 * len(arr_cambios)) + 0.1960429 <= 6: y = 6 else: y = (0.19278254662030184 * len(arr_cambios)) + 0.1960429 y = np.ceil(y) fig, ax = plt.subplots(figsize=(8, y)) data = arr_cambios columns = ("Tipo", "Subzona Hidrográfica") ax.set_title(f"CAMBIOS EN LAS ALERTAS HIDROLÓGICAS\nDEL {fecha} AL {last_datetime}\n") ax.axis('off') #ax.plot(0.5,0.891-(0.036*20), marker = 'o',markersize=12,linestyle = 'None',color='green') table = ax.table(cellText=data, colLabels=columns, loc=8,cellLoc='center',colWidths=[0.3,0.7],edges='open') table.auto_set_font_size(False) table.set_fontsize(8) cells = table.properties()["celld"] for i in range(0, 2): cells[0, i].set_text_props(fontweight="bold",fontsize=10) else: fig = 'SIN DATOS' display(fig, target="fig") def selectChange(event): pass #fig = document.getElementById("select_fig").value #date = document.getElementById("date_picker").value #document.getElementById("fig").innerHTML = "" #display(fig,target="fig") #display(date,target="fig") #plot(choice) def setup(): change_proxy = create_proxy(selectChange) e = document.getElementById("select_fig") e.addEventListener("change", change_proxy) def callback(*events): for event in events: document.getElementById("date_picker").value = event.new def date_picker(): pn.extension() datetime_picker = pn.widgets.DatetimePicker(value=last_datetime).servable(target='date_picker') document.getElementById("date_picker").value = datetime_picker.value datetime_picker.param.watch(callback, 'value') def display_fig(): fig = document.getElementById("select_fig").value date = document.getElementById("date_picker").value document.getElementById("fig").innerHTML = "" if fig == "area" or fig == "zona": plot_alertas(fig,date) elif fig == "subzona": plot_subzona(date) elif fig == "cambios": plot_cambios(date) alertas = pd.read_csv(open_url("http://fews.ideam.gov.co/colombia/Alertas/SZHCsv_hist.csv"),sep=",", keep_default_na=False) last_alertas = pd.read_csv(open_url("http://fews.ideam.gov.co/colombia/Alertas/ReporteTablaAlertas.csv"),sep=",", keep_default_na=False) subzonas = pd.read_csv("http://bart.ideam.gov.co/ospa/shape/SubzonasHidrograficas/cod_subzh.csv",sep=";", keep_default_na=False, encoding="UTF-8") areas = { 1: "Caribe" , 2: "Magdalena-Cauca" , 3: "Orinoco" , 4: "Amazonas" , 5: "Pacífico"} zonas = {11:"Río Atrato",12:"Río León",13:"Río Sinú",14:"Dique - Bocas",15:"Guajira",16:"Río Catatumbo",17:"Islas del Caribe", 21:"Alto Magdalena",22:"Río Saldaña",23:"Medio Magdalena",24:"Río Sogamoso",25:"Bajo Magdalena",26:"Río Cauca",27:"Río Nechí",28:"Río Cesar",29:"Costa", 31:"Río Inírida",32:"Río Guaviare",33:"Río Vichada",34:"Río Tomo",35:"Río Meta",36:"Río Casanare",37:"Río Arauca",38:"Río Orinoco", 41:"Río Guainía",42:"Río Vaupés",43:"Río Apaporis",44:"Alto Caquetá",45:"Río Yarí",46:"Río Caguán",47:"Río Putumayo",48:"Varios Amazonas", 51:"Mira",52:"Río Patía",53:"Patía-San Juan",54:"Río San Juan",55:"Río Baudó",56:"Baudó-Panamá",57:"Islas del Pacifíco" } colores= ['#4F00AD','#FFF300','#FF9700','#FF0000'] last_str = alertas['GMT-5'].iat[-1] last_datetime = datetime.datetime.strptime(last_str, '%Y-%m-%d %H:%M:%S') map_data = pd.read_csv(open_url("http://fews.ideam.gov.co/colombia/Alertas/ReporteTablaAlertas.csv"),sep=",", keep_default_na=False) map_dict = map_data.set_index('id')['Alerta'].to_dict() color_scale = StepColormap(['#4F00AD','green','#FFF300','#FF9700','#FF0000'], vmin = -1, vmax = 3) geo_json = json.loads(open_url('http://bart.ideam.gov.co/ospa/shape/SubzonasHidrograficas/szh_colombia_2013.geojson').read()) def get_color(feature): value = map_dict.get(feature['properties']['SZH']) if value is None: return '#8c8c8c' # MISSING -> gray else: return color_scale(value) f = folium.Figure(width="40%", height="100%") m = folium.Map(location= [4,-72], tiles="openstreetmap", zoom_start=5).add_to(f) folium.GeoJson( data = geo_json, tooltip= GeoJsonTooltip(['NOMAH','NOMZH','NOMSZH','SZH'], aliases=['AH','ZH','SUBZH','COD SUBZH'], labels=True), style_function = lambda feature: { 'fillColor': get_color(feature), 'fillOpacity': 0.5, 'color' : 'black', 'weight' : 1, } ).add_to(m) # Intitially call plot with 'area' date_picker() setup() display(m,target="map")