hedtorresca commited on
Commit
aa2a35d
·
verified ·
1 Parent(s): 60f7cb1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -54
app.py CHANGED
@@ -1,8 +1,8 @@
 
1
  import gradio as gr
2
  import pandas as pd
3
  import numpy as np
4
  import geopandas as gpd
5
- import plotly.express as px
6
  import matplotlib.pyplot as plt
7
  import seaborn as sns
8
  import folium
@@ -19,6 +19,7 @@ data = data.dropna(subset=['latitud', 'longitud'])
19
  data['geometry'] = data.apply(lambda row: Point(row['longitud'], row['latitud']), axis=1)
20
  data = gpd.GeoDataFrame(data, geometry='geometry', crs='EPSG:4326')
21
 
 
22
  geo_localidades = gpd.read_file("loca.json")
23
  geo_localidades.columns = geo_localidades.columns.str.lower()
24
  geo_localidades = geo_localidades.rename(columns={"locnombre": "localidad"})
@@ -71,96 +72,135 @@ def aplicar_filtros(df, genero, edad_rango, localidades, compromiso_renal, antec
71
  df_filtrado = df_filtrado[df_filtrado[ant] == 1]
72
  return df_filtrado
73
 
74
- # Univariado
75
- def generar_univariado(variable, genero, edad, localidades, compromiso_renal, antecedentes):
76
- df_filtrado = aplicar_filtros(data, genero, edad, localidades, compromiso_renal, antecedentes)
77
- if df_filtrado.empty:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  return None
79
  plt.figure(figsize=(6, 4))
80
- if df_filtrado[variable].dtype == 'object':
81
- sns.countplot(data=df_filtrado, x=variable)
82
  else:
83
- sns.histplot(df_filtrado[variable], kde=True)
84
- plt.title(f"Distribución de {variable}")
85
- path = f"uni_{variable}.png"
86
  plt.tight_layout()
87
  plt.savefig(path)
88
  plt.close()
89
  return path
90
 
91
- # Bivariado
92
- def generar_bivariado(xvar, yvar, genero, edad, localidades, compromiso_renal, antecedentes):
93
- df_filtrado = aplicar_filtros(data, genero, edad, localidades, compromiso_renal, antecedentes)
94
- if df_filtrado.empty:
95
  return None
96
  plt.figure(figsize=(6, 4))
97
- if df_filtrado[xvar].dtype == 'object' or df_filtrado[yvar].dtype == 'object':
98
- sns.countplot(data=df_filtrado, x=xvar, hue=yvar)
99
  else:
100
- sns.scatterplot(data=df_filtrado, x=xvar, y=yvar)
101
- plt.title(f"{xvar} vs {yvar}")
102
- path = f"bi_{xvar}_{yvar}.png"
103
  plt.tight_layout()
104
  plt.savefig(path)
105
  plt.close()
106
  return path
107
 
108
- # Interfaz con pestañas
109
  def lanzar_app():
110
  with gr.Blocks() as demo:
111
- gr.Markdown("## Tablero Interactivo: Vasculitis ANCA")
112
 
113
  with gr.Row():
114
  genero = gr.Dropdown(label="Género", choices=["Todos", "Masculino", "Femenino"], value="Todos")
115
  edad = gr.Slider(label="Edad", minimum=0, maximum=100, value=(20, 80))
116
  with gr.Row():
117
  localidades = gr.Dropdown(label="Localidades", choices=sorted(data['localidad'].dropna().unique()), multiselect=True)
118
- compromiso_renal = gr.Dropdown(label="Compromiso Renal", choices=["Todos", "Sí", "No"], value="Todos")
119
  antecedentes = gr.CheckboxGroup(label="Antecedentes", choices=["diabetes", "hta", "epoc", "falla_cardiaca"])
120
 
121
  with gr.Tab("Mapa Coroplético"):
122
  capas = gr.CheckboxGroup(label="Capas Ambientales", choices=list(capas_ambientales.keys()))
123
- btn_coro = gr.Button("Generar Mapa")
124
- mapa_html = gr.HTML()
125
-
126
- def mostrar_mapa(genero, edad, localidades, compromiso_renal, antecedentes, capas):
127
- df_f = aplicar_filtros(data, genero, edad, localidades, compromiso_renal, antecedentes)
128
- return generar_mapa_coropletico(df_f, capas)
129
-
130
- btn_coro.click(mostrar_mapa, inputs=[genero, edad, localidades, compromiso_renal, antecedentes, capas], outputs=mapa_html)
131
 
132
  with gr.Tab("Mapa de Calor"):
133
- btn_heat = gr.Button("Generar Mapa de Calor")
134
- mapa_heat = gr.HTML()
135
-
136
- def mostrar_heat(genero, edad, localidades, compromiso_renal, antecedentes):
137
- df_f = aplicar_filtros(data, genero, edad, localidades, compromiso_renal, antecedentes)
138
- return generar_mapa_calor(df_f)
139
-
140
- btn_heat.click(mostrar_heat, inputs=[genero, edad, localidades, compromiso_renal, antecedentes], outputs=mapa_heat)
141
 
142
  with gr.Tab("Univariado"):
143
- variable_uni = gr.Dropdown(label="Variable", choices=['edad', 'genero_cat', 'estrato_cat', 'anca_y_renal', 'sindrome'])
144
- btn_uni = gr.Button("Graficar")
145
- img_uni = gr.Image()
146
- btn_uni.click(generar_univariado, inputs=[variable_uni, genero, edad, localidades, compromiso_renal, antecedentes], outputs=img_uni)
147
 
148
  with gr.Tab("Bivariado"):
149
- xvar = gr.Dropdown(label="Variable X", choices=['genero_cat', 'estrato_cat', 'edad', 'mpo_cat'])
150
- yvar = gr.Dropdown(label="Variable Y", choices=['anca_y_renal', 'biopsia_positiva', 'creatinina'])
151
- btn_bi = gr.Button("Graficar")
152
- img_bi = gr.Image()
153
- btn_bi.click(generar_bivariado, inputs=[xvar, yvar, genero, edad, localidades, compromiso_renal, antecedentes], outputs=img_bi)
154
 
155
  with gr.Tab("Ayuda"):
156
  gr.Markdown("""
157
- **Guía de uso:**
158
- - Seleccione los filtros para género, edad, localidad y antecedentes clínicos.
159
- - Vaya a cada pestaña para generar los gráficos correspondientes.
160
- - Mapa de calor: muestra concentración espacial de casos.
161
- - Mapa coroplético: muestra número de casos por localidad, con opción de superponer factores ambientales.
162
- - Gráficos univariados: muestra distribución de una variable.
163
- - Gráficos bivariados: relación entre dos variables relevantes.
164
  """)
165
 
166
  demo.launch()
 
1
+ # app.py
2
  import gradio as gr
3
  import pandas as pd
4
  import numpy as np
5
  import geopandas as gpd
 
6
  import matplotlib.pyplot as plt
7
  import seaborn as sns
8
  import folium
 
19
  data['geometry'] = data.apply(lambda row: Point(row['longitud'], row['latitud']), axis=1)
20
  data = gpd.GeoDataFrame(data, geometry='geometry', crs='EPSG:4326')
21
 
22
+ # Localidades
23
  geo_localidades = gpd.read_file("loca.json")
24
  geo_localidades.columns = geo_localidades.columns.str.lower()
25
  geo_localidades = geo_localidades.rename(columns={"locnombre": "localidad"})
 
72
  df_filtrado = df_filtrado[df_filtrado[ant] == 1]
73
  return df_filtrado
74
 
75
+ # Mapa coroplético
76
+ def generar_mapa_coropletico(df, capas):
77
+ df_grouped = df.groupby('localidad').size().reset_index(name='casos')
78
+ geo_local_copy = geo_localidades.merge(df_grouped, on='localidad', how='left').fillna({'casos': 0})
79
+ m = folium.Map(location=[4.65, -74.1], zoom_start=11)
80
+ folium.Choropleth(
81
+ geo_data=geo_local_copy,
82
+ name='Casos por localidad',
83
+ data=geo_local_copy,
84
+ columns=['localidad', 'casos'],
85
+ key_on='feature.properties.localidad',
86
+ fill_color='YlOrRd',
87
+ fill_opacity=0.7,
88
+ line_opacity=0.3,
89
+ legend_name='Número de casos'
90
+ ).add_to(m)
91
+
92
+ for _, row in geo_local_copy.iterrows():
93
+ folium.Marker(
94
+ location=row['geometry'].centroid.coords[0][::-1],
95
+ popup=f"{row['localidad']}: {int(row['casos'])} casos",
96
+ icon=folium.Icon(color='blue', icon='info-sign')
97
+ ).add_to(m)
98
+
99
+ for _, row in df.iterrows():
100
+ folium.CircleMarker(
101
+ location=(row['latitud'], row['longitud']),
102
+ radius=4,
103
+ popup=f"Edad: {row['edad']}, Género: {row['genero_cat']}, Estrato: {row['estrato_cat']}, Creatinina: {row.get('creatinina', '')}",
104
+ color='black', fill=True, fill_opacity=0.6
105
+ ).add_to(m)
106
+
107
+ for capa in capas:
108
+ if capa in capas_ambientales:
109
+ gdf = capas_ambientales[capa]
110
+ folium.GeoJson(gdf, name=capa, tooltip=folium.GeoJsonTooltip(fields=gdf.columns[:2].tolist())).add_to(m)
111
+
112
+ folium.LayerControl().add_to(m)
113
+ return m._repr_html_()
114
+
115
+ # Mapa calor
116
+ def generar_mapa_calor(df):
117
+ m = folium.Map(location=[4.65, -74.1], zoom_start=11)
118
+ if df.empty:
119
+ return m._repr_html_()
120
+ heat_data = df[['latitud', 'longitud']].dropna().values.tolist()
121
+ HeatMap(heat_data, radius=14).add_to(m)
122
+ return m._repr_html_()
123
+
124
+ # Gráfico univariado
125
+ def grafico_univariado(var, genero, edad, localidades, compromiso_renal, antecedentes):
126
+ df = aplicar_filtros(data, genero, edad, localidades, compromiso_renal, antecedentes)
127
+ if df.empty:
128
  return None
129
  plt.figure(figsize=(6, 4))
130
+ if df[var].dtype == 'object':
131
+ sns.countplot(data=df, x=var)
132
  else:
133
+ sns.histplot(df[var], kde=True)
134
+ plt.title(f"Distribución de {var}")
135
+ path = f"uni_{var}.png"
136
  plt.tight_layout()
137
  plt.savefig(path)
138
  plt.close()
139
  return path
140
 
141
+ # Gráfico bivariado
142
+ def grafico_bivariado(x, y, genero, edad, localidades, compromiso_renal, antecedentes):
143
+ df = aplicar_filtros(data, genero, edad, localidades, compromiso_renal, antecedentes)
144
+ if df.empty:
145
  return None
146
  plt.figure(figsize=(6, 4))
147
+ if df[x].dtype == 'object' or df[y].dtype == 'object':
148
+ sns.countplot(data=df, x=x, hue=y)
149
  else:
150
+ sns.scatterplot(data=df, x=x, y=y)
151
+ plt.title(f"{x} vs {y}")
152
+ path = f"bi_{x}_{y}.png"
153
  plt.tight_layout()
154
  plt.savefig(path)
155
  plt.close()
156
  return path
157
 
158
+ # Interfaz
159
  def lanzar_app():
160
  with gr.Blocks() as demo:
161
+ gr.Markdown("## 🧬 Tablero Geoespacial Interactivo: Vasculitis ANCA con Compromiso Renal")
162
 
163
  with gr.Row():
164
  genero = gr.Dropdown(label="Género", choices=["Todos", "Masculino", "Femenino"], value="Todos")
165
  edad = gr.Slider(label="Edad", minimum=0, maximum=100, value=(20, 80))
166
  with gr.Row():
167
  localidades = gr.Dropdown(label="Localidades", choices=sorted(data['localidad'].dropna().unique()), multiselect=True)
168
+ compromiso = gr.Dropdown(label="Compromiso Renal", choices=["Todos", "Sí", "No"], value="Todos")
169
  antecedentes = gr.CheckboxGroup(label="Antecedentes", choices=["diabetes", "hta", "epoc", "falla_cardiaca"])
170
 
171
  with gr.Tab("Mapa Coroplético"):
172
  capas = gr.CheckboxGroup(label="Capas Ambientales", choices=list(capas_ambientales.keys()))
173
+ btn = gr.Button("Mostrar")
174
+ mapa = gr.HTML()
175
+ btn.click(fn=lambda g, e, l, c, a, cap: generar_mapa_coropletico(aplicar_filtros(data, g, e, l, c, a), cap),
176
+ inputs=[genero, edad, localidades, compromiso, antecedentes, capas], outputs=mapa)
 
 
 
 
177
 
178
  with gr.Tab("Mapa de Calor"):
179
+ btn2 = gr.Button("Mostrar")
180
+ salida = gr.HTML()
181
+ btn2.click(fn=lambda g, e, l, c, a: generar_mapa_calor(aplicar_filtros(data, g, e, l, c, a)),
182
+ inputs=[genero, edad, localidades, compromiso, antecedentes], outputs=salida)
 
 
 
 
183
 
184
  with gr.Tab("Univariado"):
185
+ var = gr.Dropdown(label="Variable", choices=['edad', 'genero_cat', 'estrato_cat', 'anca_y_renal', 'sindrome'])
186
+ btn3 = gr.Button("Graficar")
187
+ img = gr.Image()
188
+ btn3.click(grafico_univariado, inputs=[var, genero, edad, localidades, compromiso, antecedentes], outputs=img)
189
 
190
  with gr.Tab("Bivariado"):
191
+ x = gr.Dropdown(label="X", choices=['genero_cat', 'estrato_cat', 'edad', 'mpo_cat'])
192
+ y = gr.Dropdown(label="Y", choices=['anca_y_renal', 'biopsia_positiva', 'creatinina'])
193
+ btn4 = gr.Button("Graficar")
194
+ img2 = gr.Image()
195
+ btn4.click(grafico_bivariado, inputs=[x, y, genero, edad, localidades, compromiso, antecedentes], outputs=img2)
196
 
197
  with gr.Tab("Ayuda"):
198
  gr.Markdown("""
199
+ **Instrucciones de uso:**
200
+ - Aplica filtros por género, edad, localidad y antecedentes.
201
+ - Visualiza mapas con o sin capas ambientales.
202
+ - Compara variables clínicas por localidad.
203
+ - Todos los análisis son descriptivos, sin inferencia causal directa.
 
 
204
  """)
205
 
206
  demo.launch()