Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -595,6 +595,62 @@ def cargar_excel(file):
|
|
595 |
|
596 |
return concentracion_inicial, unidad_medida, n_filas, n_replicas, df_base, "", None, ""
|
597 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
598 |
# Interfaz Gradio
|
599 |
with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
600 |
gr.Markdown("""
|
@@ -658,8 +714,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
|
658 |
estado_output = gr.Textbox(label="Estado", interactive=False)
|
659 |
graficos_output = gr.Plot(label="Gráficos de Análisis")
|
660 |
|
661 |
-
#
|
662 |
-
filas_seleccionadas = gr.
|
663 |
label="Seleccione las filas a incluir en el análisis",
|
664 |
choices=[],
|
665 |
value=[],
|
@@ -724,6 +780,27 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
|
724 |
# Informe al final
|
725 |
informe_output = gr.Markdown(elem_id="informe_output")
|
726 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
# Eventos
|
728 |
input_components = [tabla_output]
|
729 |
output_components = [estado_output, graficos_output, informe_output, tabla_output]
|
@@ -867,6 +944,37 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
|
867 |
outputs=exportar_latex_file
|
868 |
)
|
869 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
870 |
# Inicializar la interfaz con el ejemplo base
|
871 |
def iniciar_con_ejemplo():
|
872 |
n_replicas = 1
|
|
|
595 |
|
596 |
return concentracion_inicial, unidad_medida, n_filas, n_replicas, df_base, "", None, ""
|
597 |
|
598 |
+
# Funciones para la nueva pestaña de regresión Absorbancia vs Concentración
|
599 |
+
def generar_tabla_absorbancia(df, unidad_medida):
|
600 |
+
df_abs = df.copy()
|
601 |
+
# Añadir columna para absorbancia
|
602 |
+
df_abs["Absorbancia"] = None
|
603 |
+
return df_abs
|
604 |
+
|
605 |
+
def actualizar_analisis_absorbancia(df_abs, unidad_medida, filas_seleccionadas_abs):
|
606 |
+
if df_abs is None or df_abs.empty:
|
607 |
+
return None, "No se pueden generar análisis", df_abs
|
608 |
+
|
609 |
+
# Convertir filas_seleccionadas a índices
|
610 |
+
if not filas_seleccionadas_abs:
|
611 |
+
return None, "No se han seleccionado filas para el análisis", df_abs
|
612 |
+
|
613 |
+
indices_seleccionados = [int(s.split(' ')[1]) - 1 for s in filas_seleccionadas_abs]
|
614 |
+
|
615 |
+
col_concentracion = f"Concentración Predicha Numérica"
|
616 |
+
col_absorbancia = "Absorbancia"
|
617 |
+
|
618 |
+
# Convertir columnas a numérico
|
619 |
+
df_abs[col_concentracion] = pd.to_numeric(df_abs[col_concentracion], errors='coerce')
|
620 |
+
df_abs[col_absorbancia] = pd.to_numeric(df_abs[col_absorbancia], errors='coerce')
|
621 |
+
|
622 |
+
df_valid = df_abs.dropna(subset=[col_concentracion, col_absorbancia])
|
623 |
+
|
624 |
+
# Filtrar filas según las seleccionadas
|
625 |
+
df_valid = df_valid.loc[indices_seleccionados]
|
626 |
+
|
627 |
+
if len(df_valid) < 2:
|
628 |
+
return None, "Se requieren al menos dos valores para el análisis", df_abs
|
629 |
+
|
630 |
+
# Calcular la regresión
|
631 |
+
slope, intercept, r_value, p_value, std_err = stats.linregress(df_valid[col_concentracion], df_valid[col_absorbancia])
|
632 |
+
df_valid['Ajuste Lineal'] = intercept + slope * df_valid[col_concentracion]
|
633 |
+
|
634 |
+
# Generar gráfico
|
635 |
+
fig, ax = plt.subplots(figsize=(8, 6))
|
636 |
+
ax.scatter(df_valid[col_concentracion], df_valid[col_absorbancia], color='blue', label='Datos')
|
637 |
+
ax.plot(df_valid[col_concentracion], df_valid['Ajuste Lineal'], color='red', label='Ajuste Lineal')
|
638 |
+
ax.set_title('Regresión Absorbancia vs Concentración')
|
639 |
+
ax.set_xlabel('Concentración')
|
640 |
+
ax.set_ylabel('Absorbancia')
|
641 |
+
ax.legend()
|
642 |
+
ax.annotate(
|
643 |
+
f'y = {intercept:.4f} + {slope:.4f}x\n$R^2$ = {r_value**2:.4f}',
|
644 |
+
xy=(0.05, 0.95),
|
645 |
+
xycoords='axes fraction',
|
646 |
+
fontsize=12,
|
647 |
+
backgroundcolor='white',
|
648 |
+
verticalalignment='top'
|
649 |
+
)
|
650 |
+
plt.tight_layout()
|
651 |
+
|
652 |
+
return fig, "Análisis completado", df_abs
|
653 |
+
|
654 |
# Interfaz Gradio
|
655 |
with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
|
656 |
gr.Markdown("""
|
|
|
714 |
estado_output = gr.Textbox(label="Estado", interactive=False)
|
715 |
graficos_output = gr.Plot(label="Gráficos de Análisis")
|
716 |
|
717 |
+
# Reemplazamos Multiselect por CheckboxGroup
|
718 |
+
filas_seleccionadas = gr.CheckboxGroup(
|
719 |
label="Seleccione las filas a incluir en el análisis",
|
720 |
choices=[],
|
721 |
value=[],
|
|
|
780 |
# Informe al final
|
781 |
informe_output = gr.Markdown(elem_id="informe_output")
|
782 |
|
783 |
+
with gr.Tab("📈 Regresión Absorbancia vs Concentración"):
|
784 |
+
with gr.Row():
|
785 |
+
calcular_abs_btn = gr.Button("🔄 Calcular Regresión", variant="primary")
|
786 |
+
limpiar_abs_btn = gr.Button("🗑 Limpiar Datos", variant="secondary")
|
787 |
+
|
788 |
+
tabla_abs_output = gr.DataFrame(
|
789 |
+
wrap=True,
|
790 |
+
label="Tabla de Datos para Absorbancia",
|
791 |
+
interactive=True,
|
792 |
+
type="pandas",
|
793 |
+
)
|
794 |
+
|
795 |
+
filas_seleccionadas_abs = gr.CheckboxGroup(
|
796 |
+
label="Seleccione las filas a incluir en el análisis",
|
797 |
+
choices=[],
|
798 |
+
value=[],
|
799 |
+
)
|
800 |
+
|
801 |
+
estado_abs_output = gr.Textbox(label="Estado", interactive=False)
|
802 |
+
graficos_abs_output = gr.Plot(label="Gráfico de Regresión")
|
803 |
+
|
804 |
# Eventos
|
805 |
input_components = [tabla_output]
|
806 |
output_components = [estado_output, graficos_output, informe_output, tabla_output]
|
|
|
944 |
outputs=exportar_latex_file
|
945 |
)
|
946 |
|
947 |
+
# Eventos para la pestaña de Absorbancia
|
948 |
+
def actualizar_opciones_filas_abs(df):
|
949 |
+
if df is None or df.empty:
|
950 |
+
return gr.update(choices=[], value=[])
|
951 |
+
else:
|
952 |
+
opciones = [f"Fila {i+1}" for i in df.index]
|
953 |
+
return gr.update(choices=opciones, value=opciones)
|
954 |
+
|
955 |
+
def inicializar_tabla_absorbancia(df, unidad_medida):
|
956 |
+
df_abs = generar_tabla_absorbancia(df, unidad_medida)
|
957 |
+
opciones = [f"Fila {i+1}" for i in df_abs.index]
|
958 |
+
return df_abs, gr.update(choices=opciones, value=opciones)
|
959 |
+
|
960 |
+
tabla_output.change(
|
961 |
+
fn=inicializar_tabla_absorbancia,
|
962 |
+
inputs=[tabla_output, unidad_input],
|
963 |
+
outputs=[tabla_abs_output, filas_seleccionadas_abs]
|
964 |
+
)
|
965 |
+
|
966 |
+
calcular_abs_btn.click(
|
967 |
+
fn=actualizar_analisis_absorbancia,
|
968 |
+
inputs=[tabla_abs_output, unidad_input, filas_seleccionadas_abs],
|
969 |
+
outputs=[graficos_abs_output, estado_abs_output, tabla_abs_output]
|
970 |
+
)
|
971 |
+
|
972 |
+
limpiar_abs_btn.click(
|
973 |
+
fn=lambda x: (x.assign(Absorbancia=None), gr.update(value=[]), ""),
|
974 |
+
inputs=[tabla_abs_output],
|
975 |
+
outputs=[tabla_abs_output, filas_seleccionadas_abs, estado_abs_output]
|
976 |
+
)
|
977 |
+
|
978 |
# Inicializar la interfaz con el ejemplo base
|
979 |
def iniciar_con_ejemplo():
|
980 |
n_replicas = 1
|