Update app.py
Browse files
app.py
CHANGED
@@ -49,14 +49,11 @@ def ajustar_decimales_evento(df, decimales):
|
|
49 |
df = df.copy()
|
50 |
# Ajustar decimales en todas las columnas numéricas
|
51 |
for col in df.columns:
|
52 |
-
|
|
|
53 |
df[col] = df[col].round(decimales)
|
54 |
-
|
55 |
-
|
56 |
-
try:
|
57 |
-
df[col] = pd.to_numeric(df[col], errors='ignore').round(decimales)
|
58 |
-
except:
|
59 |
-
pass
|
60 |
return df
|
61 |
|
62 |
def calcular_promedio_desviacion(df, n_replicas, unidad_medida):
|
@@ -77,7 +74,7 @@ def calcular_promedio_desviacion(df, n_replicas, unidad_medida):
|
|
77 |
|
78 |
return df
|
79 |
|
80 |
-
def generar_graficos(df_valid, n_replicas, unidad_medida, estilo_grafico):
|
81 |
col_predicha_num = "Concentración Predicha Numérica"
|
82 |
col_real_promedio = f"Concentración Real Promedio ({unidad_medida})"
|
83 |
col_desviacion = f"Desviación Estándar ({unidad_medida})"
|
@@ -97,10 +94,10 @@ def generar_graficos(df_valid, n_replicas, unidad_medida, estilo_grafico):
|
|
97 |
|
98 |
# Definir estilos de gráficos
|
99 |
estilos = {
|
100 |
-
"Estilo 1": {"color_puntos": "blue", "color_linea": "green", "color_error": "lightgray"},
|
101 |
-
"Estilo 2": {"color_puntos": "red", "color_linea": "orange", "color_error": "pink"},
|
102 |
-
"Estilo 3": {"color_puntos": "purple", "color_linea": "cyan", "color_error": "gray"},
|
103 |
-
"Estilo 4": {"color_puntos": "black", "color_linea": "yellow", "color_error": "darkgray"}
|
104 |
}
|
105 |
|
106 |
estilo = estilos.get(estilo_grafico, estilos["Estilo 1"])
|
@@ -108,48 +105,52 @@ def generar_graficos(df_valid, n_replicas, unidad_medida, estilo_grafico):
|
|
108 |
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
|
109 |
|
110 |
# Gráfico de dispersión con línea de regresión
|
111 |
-
if
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
133 |
|
134 |
# Línea de ajuste
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
|
|
|
|
142 |
|
143 |
# Línea ideal
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
|
|
153 |
|
154 |
ax1.set_title('Correlación entre Concentración Predicha y Real', fontsize=14)
|
155 |
ax1.set_xlabel('Concentración Predicha', fontsize=12)
|
@@ -175,7 +176,7 @@ def generar_graficos(df_valid, n_replicas, unidad_medida, estilo_grafico):
|
|
175 |
residuos,
|
176 |
color=estilo["color_puntos"],
|
177 |
s=100,
|
178 |
-
marker=
|
179 |
label='Residuos'
|
180 |
)
|
181 |
|
@@ -261,7 +262,7 @@ Fecha: {datetime.now().strftime('%d/%m/%Y %H:%M')}
|
|
261 |
"""
|
262 |
return informe, evaluacion['estado']
|
263 |
|
264 |
-
def actualizar_analisis(df, n_replicas, unidad_medida
|
265 |
if df is None or df.empty:
|
266 |
return "Error en los datos", None, "No se pueden generar análisis", df
|
267 |
|
@@ -284,11 +285,36 @@ def actualizar_analisis(df, n_replicas, unidad_medida, estilo_grafico):
|
|
284 |
slope, intercept, r_value, p_value, std_err = stats.linregress(df_valid[col_predicha_num], df_valid[col_real_promedio])
|
285 |
df_valid['Ajuste Lineal'] = intercept + slope * df_valid[col_predicha_num]
|
286 |
|
287 |
-
|
|
|
288 |
informe, estado = generar_informe_completo(df_valid, n_replicas, unidad_medida)
|
289 |
|
290 |
return estado, fig, informe, df
|
291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
292 |
def exportar_informe_word(df_valid, informe_md, unidad_medida):
|
293 |
# Crear documento Word
|
294 |
doc = docx.Document()
|
@@ -534,13 +560,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
|
534 |
ejemplo_od_btn = gr.Button("📋 Cargar Ejemplo OD", variant="secondary")
|
535 |
sinteticos_btn = gr.Button("🧪 Generar Datos Sintéticos", variant="secondary")
|
536 |
|
537 |
-
with gr.Row():
|
538 |
-
estilo_grafico_dropdown = gr.Dropdown(
|
539 |
-
choices=["Estilo 1", "Estilo 2", "Estilo 3", "Estilo 4"],
|
540 |
-
value="Estilo 1",
|
541 |
-
label="Estilo del Gráfico"
|
542 |
-
)
|
543 |
-
|
544 |
tabla_output = gr.DataFrame(
|
545 |
wrap=True,
|
546 |
label="Tabla de Datos",
|
@@ -553,6 +572,17 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
|
553 |
graficos_output = gr.Plot(label="Gráficos de Análisis")
|
554 |
informe_output = gr.Markdown(elem_id="informe_output")
|
555 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
556 |
with gr.Row():
|
557 |
copiar_btn = gr.Button("📋 Copiar Informe", variant="secondary")
|
558 |
exportar_word_btn = gr.Button("💾 Exportar Informe Word", variant="primary")
|
@@ -568,10 +598,17 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
|
568 |
# Evento al presionar el botón Calcular
|
569 |
calcular_btn.click(
|
570 |
fn=actualizar_analisis,
|
571 |
-
inputs=[tabla_output, replicas_slider, unidad_input
|
572 |
outputs=output_components
|
573 |
)
|
574 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
575 |
# Evento para limpiar datos
|
576 |
limpiar_btn.click(
|
577 |
fn=limpiar_datos,
|
@@ -674,7 +711,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
|
674 |
df = generar_tabla(7, 2000000, "UFC", n_replicas)
|
675 |
# Valores reales de ejemplo
|
676 |
df[f"Concentración Real 1 (UFC)"] = [2000000, 1600000, 1200000, 800000, 400000, 200000, 100000]
|
677 |
-
estado, fig, informe, df = actualizar_analisis(df, n_replicas, "UFC"
|
678 |
return (
|
679 |
2000000,
|
680 |
"UFC",
|
|
|
49 |
df = df.copy()
|
50 |
# Ajustar decimales en todas las columnas numéricas
|
51 |
for col in df.columns:
|
52 |
+
try:
|
53 |
+
df[col] = pd.to_numeric(df[col], errors='ignore')
|
54 |
df[col] = df[col].round(decimales)
|
55 |
+
except:
|
56 |
+
pass
|
|
|
|
|
|
|
|
|
57 |
return df
|
58 |
|
59 |
def calcular_promedio_desviacion(df, n_replicas, unidad_medida):
|
|
|
74 |
|
75 |
return df
|
76 |
|
77 |
+
def generar_graficos(df_valid, n_replicas, unidad_medida, estilo_grafico, mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos):
|
78 |
col_predicha_num = "Concentración Predicha Numérica"
|
79 |
col_real_promedio = f"Concentración Real Promedio ({unidad_medida})"
|
80 |
col_desviacion = f"Desviación Estándar ({unidad_medida})"
|
|
|
94 |
|
95 |
# Definir estilos de gráficos
|
96 |
estilos = {
|
97 |
+
"Estilo 1": {"color_puntos": "blue", "color_linea": "green", "color_error": "lightgray", "marker": "o", "line_style": "-"},
|
98 |
+
"Estilo 2": {"color_puntos": "red", "color_linea": "orange", "color_error": "pink", "marker": "s", "line_style": "--"},
|
99 |
+
"Estilo 3": {"color_puntos": "purple", "color_linea": "cyan", "color_error": "gray", "marker": "^", "line_style": "-."},
|
100 |
+
"Estilo 4": {"color_puntos": "black", "color_linea": "yellow", "color_error": "darkgray", "marker": "D", "line_style": ":"}
|
101 |
}
|
102 |
|
103 |
estilo = estilos.get(estilo_grafico, estilos["Estilo 1"])
|
|
|
105 |
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
|
106 |
|
107 |
# Gráfico de dispersión con línea de regresión
|
108 |
+
if mostrar_puntos:
|
109 |
+
if n_replicas > 1:
|
110 |
+
# Incluir barras de error
|
111 |
+
ax1.errorbar(
|
112 |
+
df_valid[col_predicha_num],
|
113 |
+
df_valid[col_real_promedio],
|
114 |
+
yerr=df_valid[col_desviacion],
|
115 |
+
fmt=estilo["marker"],
|
116 |
+
color=estilo["color_puntos"],
|
117 |
+
ecolor=estilo["color_error"],
|
118 |
+
elinewidth=2,
|
119 |
+
capsize=3,
|
120 |
+
label='Datos Reales'
|
121 |
+
)
|
122 |
+
else:
|
123 |
+
ax1.scatter(
|
124 |
+
df_valid[col_predicha_num],
|
125 |
+
df_valid[col_real_promedio],
|
126 |
+
color=estilo["color_puntos"],
|
127 |
+
s=100,
|
128 |
+
label='Datos Reales',
|
129 |
+
marker=estilo["marker"]
|
130 |
+
)
|
131 |
|
132 |
# Línea de ajuste
|
133 |
+
if mostrar_linea_ajuste:
|
134 |
+
ax1.plot(
|
135 |
+
df_valid[col_predicha_num],
|
136 |
+
df_valid['Ajuste Lineal'],
|
137 |
+
color=estilo["color_linea"],
|
138 |
+
label='Ajuste Lineal',
|
139 |
+
linewidth=2,
|
140 |
+
linestyle=estilo["line_style"]
|
141 |
+
)
|
142 |
|
143 |
# Línea ideal
|
144 |
+
if mostrar_linea_ideal:
|
145 |
+
min_predicha = df_valid[col_predicha_num].min()
|
146 |
+
max_predicha = df_valid[col_predicha_num].max()
|
147 |
+
ax1.plot(
|
148 |
+
[min_predicha, max_predicha],
|
149 |
+
[min_predicha, max_predicha],
|
150 |
+
color='red',
|
151 |
+
linestyle='--',
|
152 |
+
label='Ideal'
|
153 |
+
)
|
154 |
|
155 |
ax1.set_title('Correlación entre Concentración Predicha y Real', fontsize=14)
|
156 |
ax1.set_xlabel('Concentración Predicha', fontsize=12)
|
|
|
176 |
residuos,
|
177 |
color=estilo["color_puntos"],
|
178 |
s=100,
|
179 |
+
marker=estilo["marker"],
|
180 |
label='Residuos'
|
181 |
)
|
182 |
|
|
|
262 |
"""
|
263 |
return informe, evaluacion['estado']
|
264 |
|
265 |
+
def actualizar_analisis(df, n_replicas, unidad_medida):
|
266 |
if df is None or df.empty:
|
267 |
return "Error en los datos", None, "No se pueden generar análisis", df
|
268 |
|
|
|
285 |
slope, intercept, r_value, p_value, std_err = stats.linregress(df_valid[col_predicha_num], df_valid[col_real_promedio])
|
286 |
df_valid['Ajuste Lineal'] = intercept + slope * df_valid[col_predicha_num]
|
287 |
|
288 |
+
# Generar gráfico con opciones predeterminadas
|
289 |
+
fig = generar_graficos(df_valid, n_replicas, unidad_medida, "Estilo 1", True, True, True)
|
290 |
informe, estado = generar_informe_completo(df_valid, n_replicas, unidad_medida)
|
291 |
|
292 |
return estado, fig, informe, df
|
293 |
|
294 |
+
def actualizar_graficos(df, n_replicas, unidad_medida, estilo_grafico, mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos):
|
295 |
+
if df is None or df.empty:
|
296 |
+
return None
|
297 |
+
|
298 |
+
# Asegurarse de que los cálculos estén actualizados
|
299 |
+
df = calcular_promedio_desviacion(df, n_replicas, unidad_medida)
|
300 |
+
|
301 |
+
col_predicha_num = "Concentración Predicha Numérica"
|
302 |
+
col_real_promedio = f"Concentración Real Promedio ({unidad_medida})"
|
303 |
+
|
304 |
+
# Convertir columnas a numérico
|
305 |
+
df[col_predicha_num] = pd.to_numeric(df[col_predicha_num], errors='coerce')
|
306 |
+
df[col_real_promedio] = pd.to_numeric(df[col_real_promedio], errors='coerce')
|
307 |
+
|
308 |
+
df_valid = df.dropna(subset=[col_predicha_num, col_real_promedio])
|
309 |
+
|
310 |
+
if len(df_valid) < 2:
|
311 |
+
return None
|
312 |
+
|
313 |
+
# Generar gráfico con opciones seleccionadas
|
314 |
+
fig = generar_graficos(df_valid, n_replicas, unidad_medida, estilo_grafico, mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos)
|
315 |
+
|
316 |
+
return fig
|
317 |
+
|
318 |
def exportar_informe_word(df_valid, informe_md, unidad_medida):
|
319 |
# Crear documento Word
|
320 |
doc = docx.Document()
|
|
|
560 |
ejemplo_od_btn = gr.Button("📋 Cargar Ejemplo OD", variant="secondary")
|
561 |
sinteticos_btn = gr.Button("🧪 Generar Datos Sintéticos", variant="secondary")
|
562 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
563 |
tabla_output = gr.DataFrame(
|
564 |
wrap=True,
|
565 |
label="Tabla de Datos",
|
|
|
572 |
graficos_output = gr.Plot(label="Gráficos de Análisis")
|
573 |
informe_output = gr.Markdown(elem_id="informe_output")
|
574 |
|
575 |
+
with gr.Row():
|
576 |
+
estilo_grafico_dropdown = gr.Dropdown(
|
577 |
+
choices=["Estilo 1", "Estilo 2", "Estilo 3", "Estilo 4"],
|
578 |
+
value="Estilo 1",
|
579 |
+
label="Estilo del Gráfico"
|
580 |
+
)
|
581 |
+
mostrar_linea_ajuste = gr.Checkbox(value=True, label="Mostrar Línea de Ajuste")
|
582 |
+
mostrar_linea_ideal = gr.Checkbox(value=True, label="Mostrar Línea Ideal")
|
583 |
+
mostrar_puntos = gr.Checkbox(value=True, label="Mostrar Puntos")
|
584 |
+
graficar_btn = gr.Button("📊 Graficar", variant="primary")
|
585 |
+
|
586 |
with gr.Row():
|
587 |
copiar_btn = gr.Button("📋 Copiar Informe", variant="secondary")
|
588 |
exportar_word_btn = gr.Button("💾 Exportar Informe Word", variant="primary")
|
|
|
598 |
# Evento al presionar el botón Calcular
|
599 |
calcular_btn.click(
|
600 |
fn=actualizar_analisis,
|
601 |
+
inputs=[tabla_output, replicas_slider, unidad_input],
|
602 |
outputs=output_components
|
603 |
)
|
604 |
|
605 |
+
# Evento para graficar con opciones seleccionadas
|
606 |
+
graficar_btn.click(
|
607 |
+
fn=actualizar_graficos,
|
608 |
+
inputs=[tabla_output, replicas_slider, unidad_input, estilo_grafico_dropdown, mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos],
|
609 |
+
outputs=graficos_output
|
610 |
+
)
|
611 |
+
|
612 |
# Evento para limpiar datos
|
613 |
limpiar_btn.click(
|
614 |
fn=limpiar_datos,
|
|
|
711 |
df = generar_tabla(7, 2000000, "UFC", n_replicas)
|
712 |
# Valores reales de ejemplo
|
713 |
df[f"Concentración Real 1 (UFC)"] = [2000000, 1600000, 1200000, 800000, 400000, 200000, 100000]
|
714 |
+
estado, fig, informe, df = actualizar_analisis(df, n_replicas, "UFC")
|
715 |
return (
|
716 |
2000000,
|
717 |
"UFC",
|