# Example taken from here - https://shinylive.io/py/examples/#map import os import io from shiny import reactive, render, ui, App from plot_utils import show_one_plot, show_two_plots from data_utils import prepare_data, process_data_trees_to_temp, process_data_temp_to_trees import pandas as pd import geopandas as gpd import numpy as np og_file = "example.csv" # original_df, df, X, Y, T = prepare_data(og_file) app_ui = ui.page_fluid( ui.row( ui.column(8, ui.input_radio_buttons("tab_choice", "Seleccionar página:", ["Efecto de los árboles en la temperatura", "Efecto de la temperatura en los árboles"]), ui.output_ui("tab_slider"), ui.tooltip( ui.input_radio_buttons( "split_filter", "¿Aplicar filtro?", choices=["Sin filtro", "Filtro"], selected="Sin filtro" ), "Indica exceso de cobertura: marrón = límite por construcción, rojo = más del 100%.", placement="right" ) ), ui.column(4, ui.input_file("csv_upload", "Subir archivo CSV", accept=[".csv"]), ui.input_radio_buttons( "simulation_mode", "Modo de simulación:", choices=["Usar control deslizante", "Usar simulación personalizada del CSV"], selected="Usar control deslizante" ), ui.download_button("download_csv", "Descargar simulación (CSV)") ) ), ui.row(ui.column(12, ui.output_ui("page_ui"))) ) def server(input, output, session): @output @render.ui def tab_slider(): if input.tab_choice() == "Efecto de los árboles en la temperatura": return ui.input_slider("tree_pct", "Aumento de cobertura arbórea (%)", min=0, max=100, value=40, step=5) else: # "Effect of temperature on trees" return ui.input_slider("temp_goal", "Disminución de la temperatura (°C)", min=0, max=2, value=0.5, step=0.1) @reactive.Calc def user_data(): file_info = input.csv_upload() if file_info is None: return prepare_data(og_file) else: with open(file_info[0]["datapath"], "r", encoding="utf-8") as f: return prepare_data(f) @reactive.Calc def uploaded_filename(): file_info = input.csv_upload() if file_info is None: return "example_provided.csv" return file_info[0]["name"] @reactive.Calc def get_gdf_trees(): value_trees = input.tree_pct() simulation_mode = input.simulation_mode() print(f"value inputed is {value_trees}") original_df, df, X, Y, T = user_data() return process_data_trees_to_temp(value_trees, simulation_mode, original_df, df, X, Y, T) @reactive.Calc def get_gdf_temp(): value_temp = input.temp_goal() simulation_mode = input.simulation_mode() print(f"value inputed is {value_temp}") original_df, df, X, Y, T = user_data() return process_data_temp_to_trees(value_temp, simulation_mode, original_df, df, X, Y, T) @output @render.ui def page_ui(): if input.tab_choice() == "Efecto de los árboles en la temperatura": return ui.div( ui.h2("Visualizador de simulación: Aumento de la cobertura arbórea", class_="text-center"), ui.div(ui.output_plot("temp_after_treatment"), style="display: flex; justify-content: center;"), ui.div(ui.output_plot("temp_change"), style="display: flex; justify-content: center;"), ) else: #Effect of temperature on trees return ui.div( ui.h2("Visualizador de simulación: disminuir la temperatura", class_="text-center"), ui.div(ui.output_plot("trees_after_decrease"), style="display: flex; justify-content: center;"), ui.div(ui.output_plot("tree_coverage_change"), style="display: flex; justify-content: center;"), ) @output @render.plot() def temp_after_treatment(): gdf_trees = get_gdf_trees() value_trees = input.tree_pct() apply_filter = input.split_filter() if apply_filter == "Filtro": split = 'pct_total_trees' else: split = False min_temp = 15 max_temp = 35 simulation_mode = input.simulation_mode() title = "Temperatura estimada después del aumento de cobertura arbórea\n(simulación personalizada del CSV)" if simulation_mode == "Usar control deslizante": title = f"Temperatura estimada después del aumento de cobertura arbórea (+{value_trees}%)" try: fig = show_two_plots(gdf_trees, 'new_temp', 'LST', min_temp, max_temp, 'coolwarm',title, "Temperatura antes",'Temperatura (°C)',split=split) return fig except Exception as e: print("Plotting error:", e) raise e @output @render.plot() def temp_change(): gdf_trees = get_gdf_trees() value_trees = input.tree_pct() most_temp_change = -2 no_temp_change = 0 simulation_mode = input.simulation_mode() title = "Disminución de la temperatura después del aumento de cobertura arbórea\n(simulación personalizada del CSV)" if simulation_mode == "Usar control deslizante": title = f"Disminución de la temperatura después del aumento de cobertura arbórea (+{value_trees}%) " fig = show_one_plot(gdf_trees, 'temp_decrease', most_temp_change, no_temp_change, 'PuBu_r', title, "Cambio de temperatura (°C)") return fig @output @render.plot() def trees_after_decrease(): gdf_temp = get_gdf_temp() value_temp = input.temp_goal() apply_filter = input.split_filter() if apply_filter == "Filtro": split = 'pct_total_trees' else: split = False min_cobertura_veg = 5 max_cobertura = 100 simulation_mode = input.simulation_mode() title = "Estimación de cobertura arbórea necesaria para la disminución de temperatura\n(simulación personalizada del CSV)" if simulation_mode == "Usar control deslizante": title = f"Estimación de cobertura arbórea necesaria para una disminución de {value_temp}°C" try: fig = show_two_plots(gdf_temp, 'pct_total_trees', 'Pct_CoberturaVeg', min_cobertura_veg, max_cobertura, 'YlGn', title,"Cobertura arbórea antes", "Cobertura arbórea (%)", split=split) return fig except Exception as e: print("Plotting error:", e) raise e @output @render.plot() def tree_coverage_change(): gdf_temp = get_gdf_temp() value_temp = input.temp_goal() min_tree_increase = 0 max_tree_increase = 90 simulation_mode = input.simulation_mode() title = "Aumento de cobertura arbórea necesario para la disminución de temperatura\n(simulación personalizada del CSV)" if simulation_mode == "Usar control deslizante": title = f"Aumento de cobertura arbórea necesario para disminución de {value_temp}°C" fig = show_one_plot(gdf_temp, 'pp_trees_increase', min_tree_increase, max_tree_increase, 'Greens', title, "Cambio en cobertura arbórea (%pt)") return fig def get_filename(): simulation_mode = input.simulation_mode() uploaded_name = uploaded_filename() print(uploaded_name) if simulation_mode == "Usar control deslizante": if input.tab_choice() == "Efecto de los árboles en la temperatura": filename = f"simulacion_arboles_{input.tree_pct()}pct.csv" else: filename = f"simulacion_temp_{input.temp_goal()}C.csv" else: if input.tab_choice() == "Efecto de los árboles en la temperatura": filename = f"simulacion_arboles_desde_{uploaded_name}" else: filename = f"simulacion_temp_desde_{uploaded_name}" return filename @output @render.download(filename=lambda: get_filename()) def download_csv(): if input.tab_choice() == "Efecto de los árboles en la temperatura": df = get_gdf_trees() else: df = get_gdf_temp() if not hasattr(df, "to_csv"): raise ValueError("Expected a DataFrame or GeoDataFrame") df = df.drop(columns="geometry", errors="ignore") buffer = io.StringIO() df.to_csv(buffer, index=False) buffer.seek(0) return buffer app = App(app_ui, server)