repda-data-explorer / app-old.py
Razkaroth
finishes explorer
0c096c9
import streamlit as st
import pandas as pd
import geopandas as gpd
from diagnostics import run_df_diagnostics
import plotly.express as px
st.set_page_config(
page_title="Explorador REPDA",
page_icon="🧊",
layout="wide",
)
st.title("Explorador REPDA")
def load_data():
df = pd.read_json("data.json")
df = df.drop_duplicates()
return df
df = load_data()
# run_df_diagnostics(df, "Datos iniciales")
# Filters
st.sidebar.header("Filtros")
categorical_columns = {
"Titular": "titular",
"Título": "titulo",
"Uso amparado": "uso_amparado",
"Anotaciones marginales": "anotaciones_marginales",
"Tipo de anexo": "tipo_de_anexo",
"Estado": "estado",
"Municipio": "municipio",
"Región hidrológica": "region_hidrologica",
"Cuenca": "cuenca",
"Acuífero": "acuifero",
"Acuifero homologado": "acuifero_homologado",
}
st.sidebar.write("Filtrado por region via GeoJSON")
st.sidebar.write("Instrucciones: Entra a https://geojson.io/ y dibuja un poligono")
st.sidebar.write("Despues descarga el archivo como GeoJSON y cargalo aqui")
geojson = st.sidebar.file_uploader("Cargar GeoJSON", type=["geojson"])
if geojson is not None:
gdf = gpd.read_file(geojson)
df = gpd.GeoDataFrame(df)
df["geometry"] = df.apply(
lambda row: gpd.points_from_xy([row.lon], [row.lat])[0], axis=1
)
df.set_geometry("geometry")
df = gpd.sjoin(df, gdf, op="within")
df = df.drop(columns=["geometry", "index_right"])
df = pd.DataFrame(df)
columns = st.sidebar.multiselect(
"Selecciona columnas para filtrar por valor",
categorical_columns.keys(),
)
if columns:
for column in columns:
key = categorical_columns[column]
column_filters = st.sidebar.multiselect(
f"Selecciona valores para: {column}",
df[key].unique().tolist(),
)
if column_filters:
df = df[df[key].isin(column_filters)]
numeric_columns = {
"Volumen total de aguas nacionales": "volumen_total_de_aguas_nacionales",
"Volumen total de aguas superficiales": "volumen_total_de_aguas_superficiales",
"Volumen total de aguas subterráneas": "volumen_total_de_aguas_subterraneas",
"Volumen total de descargas": "volumen_total_de_descargas",
"Número de descargas en el título": "anexos_descargas",
"Número de tomas subtarráneas en el título": "anexos_subterraneos",
"Número de tomas superficiales en el título": "anexos_superficiales",
"Número de tomas en zonas federales en el título": "anexos_zonas_federales",
"Volumen individual": "volumen",
"Superficie": "superficie",
"Volumen de descarga diario": "volumen_de_descarga_diario",
"Volumen de descarga anual": "volumen_de_descarga_anual",
}
# Check if there are not None values in columns
numeric_columns_alive = {}
other_category_columns = (
set(df.columns.tolist())
- set(numeric_columns.values())
- set(categorical_columns.values())
)
other_catergory_columns_alive = {}
for key in other_category_columns:
if df[key].notnull().any():
other_catergory_columns_alive[key.capitalize().replace("_", " ")] = key
if other_catergory_columns_alive.keys() != []:
other_category_columns = st.sidebar.multiselect(
"Selecciona columnas para filtrar",
other_catergory_columns_alive.keys(),
)
if other_category_columns:
for key in other_category_columns:
column_name = other_catergory_columns_alive[key]
column_filters = st.sidebar.multiselect(
f"Selecciona valores para: {key}",
df[column_name].unique().tolist(),
)
if column_filters:
df = df[df[column_name].isin(column_filters)]
for key, column_name in numeric_columns.items():
if df[column_name].notnull().any():
if df[column_name].min() != df[column_name].max():
numeric_columns_alive[key] = column_name
if numeric_columns_alive.keys() != []:
numeric_column_filters = st.sidebar.multiselect(
"Selecciona columnas para filtrar por rango",
numeric_columns_alive.keys(),
)
if numeric_column_filters:
for key in numeric_column_filters:
column_name = numeric_columns_alive[key]
st.sidebar.write(f"Escoge un rango para: {key}")
min_value = st.sidebar.slider(
f"Valor mínimo para: {key}",
df[column_name].min(),
df[column_name].max(),
df[column_name].min(),
)
max_value = st.sidebar.slider(
f"Valor máximo para: {key}",
df[column_name].min(),
df[column_name].max(),
df[column_name].max(),
)
# drop rows that are NONE for that column
df = df[(df[column_name] >= min_value) & (df[column_name] <= max_value)]
# run_df_diagnostics(df, "Datos filtrados")
st.header("Mapa")
mapbox = px.scatter_mapbox(
df,
lat="lat",
lon="lon",
color="tipo_de_anexo",
hover_name="titular",
hover_data=[
"titulo",
"estado",
"municipio",
"region_hidrologica",
"cuenca",
"acuifero",
],
color_discrete_sequence=px.colors.qualitative.Vivid,
zoom=4,
height=900,
width=1000,
center={"lat": 23.634501, "lon": -102.552784},
mapbox_style="carto-positron",
)
mapbox.update_traces(marker={"size": 8})
st.plotly_chart(mapbox)
st.header("Datos")
st.dataframe(df)
st.download_button(
label="Descargar datos",
data=df.to_csv().encode("utf-8"),
file_name="data.csv",
mime="text/csv",
)