|
import streamlit as st |
|
import pandas as pd |
|
import folium |
|
from folium.plugins import MarkerCluster, Search |
|
from streamlit_folium import st_folium |
|
import html |
|
import io |
|
|
|
|
|
st.set_page_config(page_title="Puntajes SIMCE 2024 - Centros Escolares", page_icon=":school:", layout="wide") |
|
st.title(":school: Puntajes SIMCE 2024 - 2do Medio") |
|
st.markdown("Explora los puntajes SIMCE de los establecimientos educacionales en Chile (Datos del MINEDUC)") |
|
|
|
|
|
dependencia_map = { |
|
1: 'Municipal Corporaci贸n', |
|
2: 'Municipal DAEM', |
|
3: 'Particular subvencionado', |
|
4: 'Particular pagado', |
|
5: 'Corporaci贸n de administraci贸n delegada', |
|
6: 'Servicio Local de Educaci贸n' |
|
} |
|
|
|
socioecon_map = { |
|
1: 'Bajo', |
|
2: 'Medio Bajo', |
|
3: 'Medio', |
|
4: 'Medio Alto', |
|
5: 'Alto' |
|
} |
|
|
|
rural_map = { |
|
1: 'Urbano', |
|
2: 'Rural' |
|
} |
|
|
|
|
|
@st.cache_data |
|
def load_data(): |
|
df = pd.read_csv( |
|
"data/simce.csv", |
|
sep=";", |
|
decimal=",", |
|
encoding="ISO-8859-1", |
|
header=0, |
|
on_bad_lines="skip" |
|
) |
|
|
|
|
|
df['dependencia_desc'] = df['dependencia'].map(dependencia_map) |
|
df['grupo_socioecon_desc'] = df['grupo_socioecon'].map(socioecon_map) |
|
df['es_rural_desc'] = df['es_rural'].map(rural_map) |
|
|
|
return df |
|
|
|
|
|
df = load_data() |
|
|
|
|
|
st.subheader("Filtros de B煤squeda") |
|
col1, col2, col3, col4 = st.columns(4) |
|
regiones = ["(Todas)"] + sorted(df["nombre_region"].dropna().unique().tolist()) |
|
ruralidades = ["(Todas)"] + sorted(df["es_rural_desc"].dropna().unique().tolist()) |
|
dependencias = ["(Todas)"] + sorted(df["dependencia_desc"].dropna().unique().tolist()) |
|
socioecons = ["(Todas)"] + sorted(df["grupo_socioecon_desc"].dropna().unique().tolist()) |
|
|
|
with col1: |
|
sel_region = st.selectbox("Regi贸n", regiones, index=0, help="Selecciona una regi贸n para filtrar los establecimientos.") |
|
with col2: |
|
sel_ruralidad = st.selectbox("Ruralidad", ruralidades, index=0, help="Filtra por tipo de 谩rea (urbana o rural).") |
|
with col3: |
|
sel_dependencia = st.selectbox("Dependencia", dependencias, index=0, help="Filtra por tipo de establecimiento.") |
|
with col4: |
|
sel_socioecon = st.selectbox("Grupo Socioecon贸mico", socioecons, index=0, help="Filtra por nivel socioecon贸mico.") |
|
|
|
|
|
df_f = df.copy() |
|
if sel_region != "(Todas)": |
|
df_f = df_f[df_f["nombre_region"] == sel_region] |
|
if sel_ruralidad != "(Todas)": |
|
df_f = df_f[df_f["es_rural_desc"] == sel_ruralidad] |
|
if sel_dependencia != "(Todas)": |
|
df_f = df_f[df_f["dependencia_desc"] == sel_dependencia] |
|
if sel_socioecon != "(Todas)": |
|
df_f = df_f[df_f["grupo_socioecon_desc"] == sel_socioecon] |
|
|
|
|
|
df_map = df_f.dropna(subset=["latitud", "longitud"]) |
|
|
|
|
|
st.subheader("Estad铆sticas Resumidas") |
|
if not df_map.empty: |
|
col_stats1, col_stats2 = st.columns(2) |
|
with col_stats1: |
|
st.metric("N煤mero de Establecimientos", len(df_map)) |
|
st.metric("Promedio Lenguaje", f"{df_map['promedio_lectura'].mean():.1f}") |
|
with col_stats2: |
|
st.metric("Promedio Matem谩ticas", f"{df_map['promedio_matematica'].mean():.1f}") |
|
st.metric("Regiones Cubiertas", df_map["nombre_region"].nunique()) |
|
else: |
|
st.warning("No hay datos disponibles con los filtros seleccionados.") |
|
|
|
|
|
color_map = { |
|
'Municipal Corporaci贸n': 'blue', |
|
'Municipal DAEM': 'green', |
|
'Particular subvencionado': 'orange', |
|
'Particular pagado': 'purple', |
|
'Corporaci贸n de administraci贸n delegada': 'red', |
|
'Servicio Local de Educaci贸n': 'cadetblue' |
|
} |
|
|
|
|
|
def tipo_color(tipo: str) -> str: |
|
return color_map.get(tipo, "gray") |
|
|
|
|
|
m = folium.Map(location=[-33.45, -70.65], zoom_start=6, tiles="CartoDB positron") |
|
|
|
|
|
cluster = MarkerCluster().add_to(m) |
|
|
|
|
|
school_search = Search( |
|
layer=cluster, |
|
search_label="nombre_colegio", |
|
placeholder="Buscar por nombre del colegio...", |
|
collapsed=False, |
|
).add_to(m) |
|
|
|
|
|
for _, r in df_map.iterrows(): |
|
lat, lon = float(r["latitud"]), float(r["longitud"]) |
|
nombre = html.escape(str(r.get("nombre_colegio", ""))) |
|
comuna = html.escape(str(r.get("nombre_comuna", ""))) |
|
tipo = html.escape(str(r.get("dependencia_desc", ""))) |
|
lenguaje = html.escape(str(r.get("promedio_lectura", ""))) |
|
matematica = html.escape(str(r.get("promedio_matematica", ""))) |
|
rural = html.escape(str(r.get("es_rural_desc", ""))) |
|
grupoeconomico = html.escape(str(r.get("grupo_socioecon_desc", ""))) |
|
popup_html = f""" |
|
<b>{nombre}</b><br> |
|
<b>Tipo:</b> {tipo}<br> |
|
<b>Comuna:</b> {comuna}<br> |
|
<b>Promedio Lenguaje:</b> {lenguaje}<br> |
|
<b>Promedio Matem谩ticas:</b> {matematica}<br> |
|
<b>Es Rural:</b> {rural}<br> |
|
<b>Grupo Socioecon贸mico:</b> {grupoeconomico} |
|
""" |
|
marker = folium.Marker( |
|
location=[lat, lon], |
|
popup=folium.Popup(popup_html, max_width=350), |
|
icon=folium.Icon(color=tipo_color(r.get("dependencia_desc")), icon="plus", prefix="fa"), |
|
) |
|
marker.add_to(cluster) |
|
marker.properties = {"nombre_colegio": nombre} |
|
|
|
|
|
legend_html = """ |
|
<div style=" |
|
position: fixed; |
|
bottom: 30px; left: 30px; z-index: 9999; |
|
background: white; padding: 12px; border: 2px solid #ccc; border-radius: 10px; |
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1); font-family: Arial, sans-serif; font-size: 14px;"> |
|
<b style="color:black; font-size: 16px;">Leyenda</b><br> |
|
<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:blue;margin-right:8px;"></span><span style="color:black;">Municipal Corporaci贸n</span><br> |
|
<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:green;margin-right:8px;"></span><span style="color:black;">Municipal DAEM</span><br> |
|
<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:orange;margin-right:8px;"></span><span style="color:black;">Particular subvencionado</span><br> |
|
<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:purple;margin-right:8px;"></span><span style="color:black;">Particular pagado</span><br> |
|
<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:red;margin-right:8px;"></span><span style="color:black;">Corporaci贸n de administraci贸n delegada</span><br> |
|
<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:cadetblue;margin-right:8px;"></span><span style="color:black;">Servicio Local de Educaci贸n</span><br> |
|
<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:gray;margin-right:8px;"></span><span style="color:black;">Otros</span> |
|
</div> |
|
""" |
|
m.get_root().html.add_child(folium.Element(legend_html)) |
|
|
|
|
|
if st.button("Reiniciar Mapa"): |
|
m = folium.Map(location=[-33.45, -70.65], zoom_start=6, tiles="CartoDB positron") |
|
st.experimental_rerun() |
|
|
|
|
|
st_folium(m, width=1200, height=650) |
|
|
|
|
|
with st.expander("Ver tabla filtrada"): |
|
columns_to_display = ['nombre_region', 'nombre_comuna', 'nombre_colegio', 'dependencia_desc', 'grupo_socioecon_desc', 'es_rural_desc', 'promedio_lectura', 'promedio_matematica'] |
|
st.dataframe(df_map[columns_to_display]) |
|
|
|
|
|
csv = df_map[columns_to_display].to_csv(index=False) |
|
st.download_button( |
|
label="Descargar datos filtrados como CSV", |
|
data=csv, |
|
file_name="simce_filtrado.csv", |
|
mime="text/csv", |
|
) |