Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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.
|
12 |
# -------------------------------
|
13 |
-
DATA_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 |
-
#
|
|
|
|
|
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 |
-
#
|
49 |
# -------------------------------
|
50 |
-
def dashboard(f_inicio, f_fin, tipos, ofis,
|
|
|
51 |
d = df.copy()
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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(
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
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 |
-
|
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
|
84 |
-
|
|
|
|
|
85 |
folium.CircleMarker(
|
86 |
location=[lat, lon],
|
87 |
radius=6,
|
88 |
-
color="
|
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 |
-
#
|
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 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
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(
|
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()
|
|