hedtorresca commited on
Commit
f771d98
·
verified ·
1 Parent(s): 753d1e2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -46
app.py CHANGED
@@ -1,6 +1,4 @@
1
  import os
2
- import json
3
- import pathlib
4
  import pandas as pd
5
  import plotly.express as px
6
  import gradio as gr
@@ -8,19 +6,18 @@ import folium
8
  from folium.plugins import MarkerCluster
9
 
10
  # -------------------------------
11
- # 1. Configuración y datos
12
  # -------------------------------
13
- DATA_XLSX = "Base de Datos Prueba.xlsx"
14
- COORDS_JSON = "office_coords.json"
15
-
16
  df = pd.read_excel(DATA_XLSX, parse_dates=["FECHA_APERTURA"])
17
  df["MES"] = df["FECHA_APERTURA"].dt.to_period("M").dt.to_timestamp()
18
-
19
- oficinas = sorted(df["OFICINA"].dropna().unique().tolist())
20
  productos = sorted(df["TIPO PRODUCTO"].dropna().unique().tolist())
21
  min_amt, max_amt = int(df["MONTO_I"].min()), int(df["MONTO_I"].max())
22
 
23
- # Coordenadas hard-coded (todas)
 
 
24
  office_coords = {
25
  "Montería Centro": (8.74733, -75.88145),
26
  "Monteria": (8.74733, -75.88145),
@@ -45,71 +42,76 @@ office_coords = {
45
  }
46
 
47
  # -------------------------------
48
- # 2. Función de filtrado y gráficos
49
  # -------------------------------
50
- def dashboard(f_inicio, f_fin, tipos, ofis, rango):
 
51
  d = df.copy()
52
- if f_inicio: d = d[d.FECHA_APERTURA >= pd.to_datetime(f_inicio)]
53
- if f_fin: d = d[d.FECHA_APERTURA <= pd.to_datetime(f_fin)]
54
- if tipos: d = d[d["TIPO PRODUCTO"].isin(tipos)]
55
- if ofis: d = d[d["OFICINA"].isin(ofis)]
56
- d = d[(d["MONTO_I"] >= rango[0]) & (d["MONTO_I"] <= rango[1])]
57
-
58
- # Gráfico 1: barras mensuales
 
 
 
 
 
 
 
59
  fig1 = px.bar(
60
  d.groupby("MES")["MONTO_I"].sum().reset_index(),
61
  x="MES", y="MONTO_I",
62
- labels={"MES":"Mes","MONTO_I":"Monto (COP)"},
63
  title="Monto desembolsado por mes"
64
  )
65
-
66
- # Gráfico 2: pie de productos
67
  df2 = d["TIPO PRODUCTO"].value_counts().reset_index()
68
  df2.columns = ["TIPO PRODUCTO","CANT"]
69
- fig2 = px.pie(df2, names="TIPO PRODUCTO", values="CANT",
70
- title="Distribución por tipo de producto")
71
-
72
- # Gráfico 3: boxplot de tasas
 
73
  fig3 = px.box(
74
  d, x="TIPO PRODUCTO", y="TASA",
75
  labels={"TASA":"Tasa (%)","TIPO PRODUCTO":"Producto"},
76
  title="Distribución de tasas de interés"
77
  )
78
-
79
- # Mapa Folium
80
- m = folium.Map(location=[4.6, -74.1], zoom_start=6, tiles="OpenStreetMap")
81
  mc = MarkerCluster().add_to(m)
82
  for ofi, (lat, lon) in office_coords.items():
83
- if lat is None or ofi not in d["OFICINA"].values: continue
84
- total = d.loc[d["OFICINA"]==ofi, "MONTO_I"].sum()
 
 
85
  folium.CircleMarker(
86
  location=[lat, lon],
87
  radius=6,
88
- color="navy",
89
  fill=True,
90
  fill_opacity=0.7,
91
  popup=f"{ofi}<br>Total: {total:,.0f} COP"
92
  ).add_to(mc)
93
  map_html = m._repr_html_()
94
-
95
  return fig1, fig2, fig3, map_html
96
 
97
  # -------------------------------
98
- # 3. Interfaz Gradio v3 (Blocks API)
99
  # -------------------------------
100
  with gr.Blocks() as demo:
101
  gr.Markdown("## Dashboard Bancamía – Aperturas Q1 2025")
102
-
103
  with gr.Row():
104
  with gr.Column(scale=1):
105
- dp1 = gr.DatePicker(label="Desde", value="2025-01-01")
106
- dp2 = gr.DatePicker(label="Hasta", value="2025-03-31")
107
- dd1 = gr.Dropdown(productos, multiselect=True, label="Tipo de Producto")
108
- dd2 = gr.Dropdown(oficinas, multiselect=True, label="Oficina")
109
- rs = gr.Slider(minimum=min_amt, maximum=max_amt, value=[min_amt, max_amt],
110
- step=1_000_000, label="Rango de Monto (COP)")
111
- btn = gr.Button("Actualizar")
112
-
113
  with gr.Column(scale=3):
114
  with gr.Tab("Monto"):
115
  out1 = gr.Plot()
@@ -119,9 +121,7 @@ with gr.Blocks() as demo:
119
  out3 = gr.Plot()
120
  with gr.Tab("Mapa"):
121
  out4 = gr.HTML()
122
-
123
- btn.click(dashboard, [dp1, dp2, dd1, dd2, rs], [out1, out2, out3, out4])
124
 
125
  if __name__ == "__main__":
126
- demo.launch(server_name="0.0.0.0",
127
- server_port=int(os.environ.get("PORT", 7860)))
 
1
  import os
 
 
2
  import pandas as pd
3
  import plotly.express as px
4
  import gradio as gr
 
6
  from folium.plugins import MarkerCluster
7
 
8
  # -------------------------------
9
+ # 1. Cargar y preparar datos
10
  # -------------------------------
11
+ DATA_XLSX = "Base de Datos Prueba.xlsx"
 
 
12
  df = pd.read_excel(DATA_XLSX, parse_dates=["FECHA_APERTURA"])
13
  df["MES"] = df["FECHA_APERTURA"].dt.to_period("M").dt.to_timestamp()
14
+ oficinas = sorted(df["OFICINA"].dropna().unique().tolist())
 
15
  productos = sorted(df["TIPO PRODUCTO"].dropna().unique().tolist())
16
  min_amt, max_amt = int(df["MONTO_I"].min()), int(df["MONTO_I"].max())
17
 
18
+ # -------------------------------
19
+ # 2. Coordenadas hard-coded
20
+ # -------------------------------
21
  office_coords = {
22
  "Montería Centro": (8.74733, -75.88145),
23
  "Monteria": (8.74733, -75.88145),
 
42
  }
43
 
44
  # -------------------------------
45
+ # 3. Función de dashboard
46
  # -------------------------------
47
+ def dashboard(f_inicio, f_fin, tipos, ofis, monto_rango):
48
+ # Parsear fechas
49
  d = df.copy()
50
+ try:
51
+ if f_inicio:
52
+ d = d[d["FECHA_APERTURA"] >= pd.to_datetime(f_inicio)]
53
+ if f_fin:
54
+ d = d[d["FECHA_APERTURA"] <= pd.to_datetime(f_fin)]
55
+ except:
56
+ pass
57
+ if tipos:
58
+ d = d[d["TIPO PRODUCTO"].isin(tipos)]
59
+ if ofis:
60
+ d = d[d["OFICINA"].isin(ofis)]
61
+ d = d[(d["MONTO_I"] >= monto_rango[0]) & (d["MONTO_I"] <= monto_rango[1])]
62
+
63
+ # Gráfico 1: Monto mensual
64
  fig1 = px.bar(
65
  d.groupby("MES")["MONTO_I"].sum().reset_index(),
66
  x="MES", y="MONTO_I",
67
+ labels={"MES":"Mes", "MONTO_I":"Monto (COP)"},
68
  title="Monto desembolsado por mes"
69
  )
70
+ # Gráfico 2: Distribución por producto
 
71
  df2 = d["TIPO PRODUCTO"].value_counts().reset_index()
72
  df2.columns = ["TIPO PRODUCTO","CANT"]
73
+ fig2 = px.pie(
74
+ df2, names="TIPO PRODUCTO", values="CANT",
75
+ title="Distribución por tipo de producto"
76
+ )
77
+ # Gráfico 3: Boxplot de tasas
78
  fig3 = px.box(
79
  d, x="TIPO PRODUCTO", y="TASA",
80
  labels={"TASA":"Tasa (%)","TIPO PRODUCTO":"Producto"},
81
  title="Distribución de tasas de interés"
82
  )
83
+ # Gráfico 4: Mapa Folium
84
+ m = folium.Map(location=[4.6, -74.1], zoom_start=6)
 
85
  mc = MarkerCluster().add_to(m)
86
  for ofi, (lat, lon) in office_coords.items():
87
+ if lat is None: continue
88
+ sub = d[d["OFICINA"] == ofi]
89
+ if sub.empty: continue
90
+ total = sub["MONTO_I"].sum()
91
  folium.CircleMarker(
92
  location=[lat, lon],
93
  radius=6,
94
+ color="blue",
95
  fill=True,
96
  fill_opacity=0.7,
97
  popup=f"{ofi}<br>Total: {total:,.0f} COP"
98
  ).add_to(mc)
99
  map_html = m._repr_html_()
 
100
  return fig1, fig2, fig3, map_html
101
 
102
  # -------------------------------
103
+ # 4. Interfaz Gradio v3-compatible
104
  # -------------------------------
105
  with gr.Blocks() as demo:
106
  gr.Markdown("## Dashboard Bancamía – Aperturas Q1 2025")
 
107
  with gr.Row():
108
  with gr.Column(scale=1):
109
+ f_inicio = gr.Textbox(label="Fecha inicio (YYYY-MM-DD)", value="2025-01-01")
110
+ f_fin = gr.Textbox(label="Fecha fin (YYYY-MM-DD)", value="2025-03-31")
111
+ tipos = gr.CheckboxGroup(choices=productos, label="Tipo de Producto")
112
+ ofis = gr.CheckboxGroup(choices=oficinas, label="Oficina")
113
+ monto = gr.Slider(min_amt, max_amt, value=[min_amt, max_amt], step=1_000_000, label="Rango Monto (COP)")
114
+ btn = gr.Button("Actualizar")
 
 
115
  with gr.Column(scale=3):
116
  with gr.Tab("Monto"):
117
  out1 = gr.Plot()
 
121
  out3 = gr.Plot()
122
  with gr.Tab("Mapa"):
123
  out4 = gr.HTML()
124
+ btn.click(dashboard, inputs=[f_inicio, f_fin, tipos, ofis, monto], outputs=[out1, out2, out3, out4])
 
125
 
126
  if __name__ == "__main__":
127
+ demo.launch()