Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -40,6 +40,7 @@ class RSM_ExperimentalDesign:
|
|
40 |
self.optimized_results = None
|
41 |
self.optimal_levels = None
|
42 |
self.all_figures = []
|
|
|
43 |
|
44 |
def generate_design(self):
|
45 |
"""
|
@@ -96,6 +97,7 @@ class RSM_ExperimentalDesign:
|
|
96 |
Args:
|
97 |
selected_factors (list): Lista de factores a incluir en el modelo.
|
98 |
"""
|
|
|
99 |
terms = selected_factors.copy()
|
100 |
# Términos cuadráticos
|
101 |
terms += [f'I({var}**2)' for var in selected_factors]
|
@@ -263,9 +265,6 @@ class RSM_ExperimentalDesign:
|
|
263 |
self.all_figures = [] # Resetear la lista de figuras
|
264 |
|
265 |
# Niveles naturales para graficar
|
266 |
-
levels_to_plot_natural = self.factor_levels
|
267 |
-
|
268 |
-
# Generar y almacenar gráficos individuales
|
269 |
for fixed_variable in self.selected_factors:
|
270 |
for level in self.factor_levels[fixed_variable]:
|
271 |
fig = self.plot_rsm_individual(fixed_variable, level)
|
@@ -382,7 +381,7 @@ class RSM_ExperimentalDesign:
|
|
382 |
f_stat = ms_factor / ms_error
|
383 |
p_value = f.sf(f_stat, df_factor, anova_table.loc['Residual', 'df'])
|
384 |
contribution_percentage = (ss_factor / ss_total) * 100
|
385 |
-
|
386 |
contribution_table = pd.concat([contribution_table, pd.DataFrame({
|
387 |
'Fuente de Variación': [factor_name],
|
388 |
'Suma de Cuadrados': [ss_factor],
|
@@ -512,19 +511,6 @@ class RSM_ExperimentalDesign:
|
|
512 |
"""
|
513 |
return fig.to_image(format="png")
|
514 |
|
515 |
-
def save_all_figures_png(self):
|
516 |
-
"""
|
517 |
-
Guarda todas las figuras en archivos PNG temporales y retorna las rutas.
|
518 |
-
"""
|
519 |
-
png_paths = []
|
520 |
-
for idx, fig in enumerate(self.all_figures, start=1):
|
521 |
-
img_bytes = fig.to_image(format="png")
|
522 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
|
523 |
-
temp_file.write(img_bytes)
|
524 |
-
temp_path = temp_file.name
|
525 |
-
png_paths.append(temp_path)
|
526 |
-
return png_paths
|
527 |
-
|
528 |
def save_tables_to_excel(self):
|
529 |
"""
|
530 |
Guarda todas las tablas en un archivo Excel con múltiples hojas y retorna la ruta del archivo.
|
@@ -705,12 +691,7 @@ def download_current_plot(all_figures, current_index):
|
|
705 |
img_bytes = rsm.save_fig_to_bytes(fig)
|
706 |
filename = f"Grafico_RSM_{current_index + 1}.png"
|
707 |
|
708 |
-
|
709 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
|
710 |
-
temp_file.write(img_bytes)
|
711 |
-
temp_path = temp_file.name
|
712 |
-
|
713 |
-
return temp_path # Retornar solo la ruta
|
714 |
|
715 |
def download_all_plots_zip():
|
716 |
"""
|
@@ -720,7 +701,10 @@ def download_all_plots_zip():
|
|
720 |
return None
|
721 |
zip_path = rsm.save_figures_to_zip()
|
722 |
if zip_path:
|
723 |
-
|
|
|
|
|
|
|
724 |
return None
|
725 |
|
726 |
def download_all_tables_excel():
|
@@ -731,18 +715,24 @@ def download_all_tables_excel():
|
|
731 |
return None
|
732 |
excel_path = rsm.save_tables_to_excel()
|
733 |
if excel_path:
|
734 |
-
|
|
|
|
|
|
|
735 |
return None
|
736 |
|
737 |
def exportar_word(tables_dict):
|
738 |
"""
|
739 |
Función para exportar las tablas a un documento de Word.
|
740 |
"""
|
741 |
-
if
|
742 |
return None
|
743 |
word_path = rsm.export_tables_to_word(tables_dict)
|
744 |
if word_path and os.path.exists(word_path):
|
745 |
-
|
|
|
|
|
|
|
746 |
return None
|
747 |
|
748 |
# --- Crear la interfaz de Gradio ---
|
@@ -817,8 +807,8 @@ def create_gradio_interface():
|
|
817 |
gr.Markdown("**Tabla ANOVA Detallada**")
|
818 |
anova_table_output = gr.Dataframe(label="Tabla ANOVA Detallada", interactive=False)
|
819 |
gr.Markdown("## Descargar Todas las Tablas")
|
820 |
-
download_excel_button = gr.
|
821 |
-
download_word_button = gr.
|
822 |
|
823 |
with gr.Column():
|
824 |
gr.Markdown("## Selección de Factores para el Modelo Simplificado")
|
@@ -828,8 +818,6 @@ def create_gradio_interface():
|
|
828 |
value=[]
|
829 |
)
|
830 |
fit_button_2 = gr.Button("Aplicar Selección de Factores")
|
831 |
-
gr.Markdown("## Resultados de Optimización")
|
832 |
-
optimization_table_output_2 = gr.Dataframe(label="Tabla de Optimización", interactive=False)
|
833 |
gr.Markdown("## Generar Gráficos de Superficie de Respuesta")
|
834 |
plot_button = gr.Button("Generar Gráficos")
|
835 |
with gr.Row():
|
@@ -838,14 +826,23 @@ def create_gradio_interface():
|
|
838 |
rsm_plot_output = gr.Plot()
|
839 |
plot_info = gr.Textbox(label="Información del Gráfico", value="Gráfico 1 de 0", interactive=False)
|
840 |
with gr.Row():
|
841 |
-
download_plot_button = gr.
|
842 |
-
download_all_plots_button = gr.
|
843 |
current_index_state = gr.State(0) # Estado para el índice actual
|
844 |
all_figures_state = gr.State([]) # Estado para todas las figuras
|
845 |
|
846 |
# Funciones de carga y ajuste
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
load_button.click(
|
848 |
-
|
849 |
inputs=[design_type_input, factor_names_input, factor_levels_input, y_name_input, data_input],
|
850 |
outputs=[data_output, analysis_row, selected_factors_input]
|
851 |
)
|
@@ -869,40 +866,55 @@ def create_gradio_interface():
|
|
869 |
]
|
870 |
)
|
871 |
|
872 |
-
#
|
873 |
download_excel_button.click(
|
874 |
-
fn=
|
875 |
inputs=[],
|
876 |
outputs=download_excel_button
|
877 |
)
|
878 |
-
|
879 |
download_word_button.click(
|
880 |
-
fn=
|
881 |
-
inputs=[],
|
882 |
outputs=download_word_button
|
883 |
)
|
884 |
|
885 |
# Generar y mostrar los gráficos
|
|
|
|
|
|
|
|
|
|
|
|
|
886 |
plot_button.click(
|
887 |
-
|
888 |
-
None, # Placeholder, se actualizará después
|
889 |
-
"No hay gráficos disponibles.",
|
890 |
-
0,
|
891 |
-
[]
|
892 |
-
),
|
893 |
inputs=[],
|
894 |
outputs=[rsm_plot_output, plot_info, current_index_state, all_figures_state]
|
895 |
)
|
896 |
|
897 |
# Navegación de gráficos
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
898 |
left_button.click(
|
899 |
-
|
900 |
-
inputs=[current_index_state, all_figures_state],
|
901 |
outputs=[rsm_plot_output, plot_info, current_index_state]
|
902 |
)
|
|
|
903 |
right_button.click(
|
904 |
-
|
905 |
-
inputs=[current_index_state, all_figures_state],
|
906 |
outputs=[rsm_plot_output, plot_info, current_index_state]
|
907 |
)
|
908 |
|
@@ -926,95 +938,25 @@ def create_gradio_interface():
|
|
926 |
1. **Configura el Diseño:**
|
927 |
- Selecciona el tipo de diseño (Box-Behnken o Central Compuesto).
|
928 |
- Ingresa los nombres de los factores separados por comas.
|
929 |
-
- Ingresa los niveles
|
930 |
- Especifica el nombre de la variable dependiente.
|
931 |
- Proporciona los datos del experimento en formato CSV.
|
932 |
2. **Cargar Datos:**
|
933 |
- Haz clic en 'Cargar Datos' para cargar y visualizar los datos.
|
934 |
-
3. **
|
935 |
-
-
|
|
|
936 |
- Haz clic en 'Ajustar Modelo y Optimizar' para ajustar los modelos y obtener los resultados.
|
937 |
-
|
938 |
- Haz clic en 'Generar Gráficos' para crear las superficies de respuesta.
|
939 |
- Navega entre los gráficos usando los botones '<' y '>'.
|
940 |
-
- Descarga el gráfico actual en PNG o
|
941 |
-
|
942 |
- Descarga todas las tablas generadas en un archivo Excel o Word.
|
943 |
""")
|
944 |
|
945 |
return demo
|
946 |
|
947 |
-
def navigate_plot(direction, current_index, all_figures):
|
948 |
-
"""
|
949 |
-
Navega entre los gráficos.
|
950 |
-
"""
|
951 |
-
if not all_figures:
|
952 |
-
return None, "No hay gráficos disponibles.", current_index
|
953 |
-
|
954 |
-
if direction == 'left':
|
955 |
-
new_index = (current_index - 1) % len(all_figures)
|
956 |
-
elif direction == 'right':
|
957 |
-
new_index = (current_index + 1) % len(all_figures)
|
958 |
-
else:
|
959 |
-
new_index = current_index
|
960 |
-
|
961 |
-
selected_fig = all_figures[new_index]
|
962 |
-
plot_info_text = f"Gráfico {new_index + 1} de {len(all_figures)}"
|
963 |
-
|
964 |
-
return selected_fig, plot_info_text, new_index
|
965 |
-
|
966 |
-
# --- Funciones de descarga y exportación ---
|
967 |
-
|
968 |
-
def download_current_plot(all_figures, current_index):
|
969 |
-
"""
|
970 |
-
Descarga la figura actual como PNG.
|
971 |
-
"""
|
972 |
-
if not all_figures:
|
973 |
-
return None
|
974 |
-
fig = all_figures[current_index]
|
975 |
-
img_bytes = rsm.save_fig_to_bytes(fig)
|
976 |
-
filename = f"Grafico_RSM_{current_index + 1}.png"
|
977 |
-
|
978 |
-
# Crear un archivo temporal
|
979 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
|
980 |
-
temp_file.write(img_bytes)
|
981 |
-
temp_path = temp_file.name
|
982 |
-
|
983 |
-
return temp_path # Retornar solo la ruta
|
984 |
-
|
985 |
-
def download_all_plots_zip():
|
986 |
-
"""
|
987 |
-
Descarga todas las figuras en un archivo ZIP.
|
988 |
-
"""
|
989 |
-
if 'rsm' not in globals():
|
990 |
-
return None
|
991 |
-
zip_path = rsm.save_figures_to_zip()
|
992 |
-
if zip_path:
|
993 |
-
return zip_path
|
994 |
-
return None
|
995 |
-
|
996 |
-
def download_all_tables_excel():
|
997 |
-
"""
|
998 |
-
Descarga todas las tablas en un archivo Excel con múltiples hojas.
|
999 |
-
"""
|
1000 |
-
if 'rsm' not in globals():
|
1001 |
-
return None
|
1002 |
-
excel_path = rsm.save_tables_to_excel()
|
1003 |
-
if excel_path:
|
1004 |
-
return excel_path
|
1005 |
-
return None
|
1006 |
-
|
1007 |
-
def exportar_word(tables_dict):
|
1008 |
-
"""
|
1009 |
-
Función para exportar las tablas a un documento de Word.
|
1010 |
-
"""
|
1011 |
-
if not tables_dict:
|
1012 |
-
return None
|
1013 |
-
word_path = rsm.export_tables_to_word(tables_dict)
|
1014 |
-
if word_path and os.path.exists(word_path):
|
1015 |
-
return word_path
|
1016 |
-
return None
|
1017 |
-
|
1018 |
# --- Función Principal ---
|
1019 |
|
1020 |
def main():
|
|
|
40 |
self.optimized_results = None
|
41 |
self.optimal_levels = None
|
42 |
self.all_figures = []
|
43 |
+
self.selected_factors = []
|
44 |
|
45 |
def generate_design(self):
|
46 |
"""
|
|
|
97 |
Args:
|
98 |
selected_factors (list): Lista de factores a incluir en el modelo.
|
99 |
"""
|
100 |
+
self.selected_factors = selected_factors
|
101 |
terms = selected_factors.copy()
|
102 |
# Términos cuadráticos
|
103 |
terms += [f'I({var}**2)' for var in selected_factors]
|
|
|
265 |
self.all_figures = [] # Resetear la lista de figuras
|
266 |
|
267 |
# Niveles naturales para graficar
|
|
|
|
|
|
|
268 |
for fixed_variable in self.selected_factors:
|
269 |
for level in self.factor_levels[fixed_variable]:
|
270 |
fig = self.plot_rsm_individual(fixed_variable, level)
|
|
|
381 |
f_stat = ms_factor / ms_error
|
382 |
p_value = f.sf(f_stat, df_factor, anova_table.loc['Residual', 'df'])
|
383 |
contribution_percentage = (ss_factor / ss_total) * 100
|
384 |
+
|
385 |
contribution_table = pd.concat([contribution_table, pd.DataFrame({
|
386 |
'Fuente de Variación': [factor_name],
|
387 |
'Suma de Cuadrados': [ss_factor],
|
|
|
511 |
"""
|
512 |
return fig.to_image(format="png")
|
513 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
514 |
def save_tables_to_excel(self):
|
515 |
"""
|
516 |
Guarda todas las tablas en un archivo Excel con múltiples hojas y retorna la ruta del archivo.
|
|
|
691 |
img_bytes = rsm.save_fig_to_bytes(fig)
|
692 |
filename = f"Grafico_RSM_{current_index + 1}.png"
|
693 |
|
694 |
+
return (filename, img_bytes)
|
|
|
|
|
|
|
|
|
|
|
695 |
|
696 |
def download_all_plots_zip():
|
697 |
"""
|
|
|
701 |
return None
|
702 |
zip_path = rsm.save_figures_to_zip()
|
703 |
if zip_path:
|
704 |
+
with open(zip_path, 'rb') as f:
|
705 |
+
zip_bytes = f.read()
|
706 |
+
filename = f"Graficos_RSM_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
|
707 |
+
return (filename, zip_bytes)
|
708 |
return None
|
709 |
|
710 |
def download_all_tables_excel():
|
|
|
715 |
return None
|
716 |
excel_path = rsm.save_tables_to_excel()
|
717 |
if excel_path:
|
718 |
+
with open(excel_path, 'rb') as f:
|
719 |
+
excel_bytes = f.read()
|
720 |
+
filename = f"Tablas_RSM_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
|
721 |
+
return (filename, excel_bytes)
|
722 |
return None
|
723 |
|
724 |
def exportar_word(tables_dict):
|
725 |
"""
|
726 |
Función para exportar las tablas a un documento de Word.
|
727 |
"""
|
728 |
+
if not tables_dict:
|
729 |
return None
|
730 |
word_path = rsm.export_tables_to_word(tables_dict)
|
731 |
if word_path and os.path.exists(word_path):
|
732 |
+
with open(word_path, 'rb') as f:
|
733 |
+
word_bytes = f.read()
|
734 |
+
filename = f"Tablas_RSM_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx"
|
735 |
+
return (filename, word_bytes)
|
736 |
return None
|
737 |
|
738 |
# --- Crear la interfaz de Gradio ---
|
|
|
807 |
gr.Markdown("**Tabla ANOVA Detallada**")
|
808 |
anova_table_output = gr.Dataframe(label="Tabla ANOVA Detallada", interactive=False)
|
809 |
gr.Markdown("## Descargar Todas las Tablas")
|
810 |
+
download_excel_button = gr.DownloadButton(label="Descargar Tablas en Excel")
|
811 |
+
download_word_button = gr.DownloadButton(label="Descargar Tablas en Word")
|
812 |
|
813 |
with gr.Column():
|
814 |
gr.Markdown("## Selección de Factores para el Modelo Simplificado")
|
|
|
818 |
value=[]
|
819 |
)
|
820 |
fit_button_2 = gr.Button("Aplicar Selección de Factores")
|
|
|
|
|
821 |
gr.Markdown("## Generar Gráficos de Superficie de Respuesta")
|
822 |
plot_button = gr.Button("Generar Gráficos")
|
823 |
with gr.Row():
|
|
|
826 |
rsm_plot_output = gr.Plot()
|
827 |
plot_info = gr.Textbox(label="Información del Gráfico", value="Gráfico 1 de 0", interactive=False)
|
828 |
with gr.Row():
|
829 |
+
download_plot_button = gr.DownloadButton(label="Descargar Gráfico Actual (PNG)")
|
830 |
+
download_all_plots_button = gr.DownloadButton(label="Descargar Todos los Gráficos (ZIP)")
|
831 |
current_index_state = gr.State(0) # Estado para el índice actual
|
832 |
all_figures_state = gr.State([]) # Estado para todas las figuras
|
833 |
|
834 |
# Funciones de carga y ajuste
|
835 |
+
def load_data_interface(design_type, factor_names, factor_levels, y_name, data_str):
|
836 |
+
data, analysis_visibility, factor_names_list = load_data(design_type, factor_names, factor_levels, y_name, data_str)
|
837 |
+
if data is not None:
|
838 |
+
# Actualizar las opciones de selección de factores
|
839 |
+
selected_factors = factor_names_list
|
840 |
+
return data, analysis_visibility, selected_factors
|
841 |
+
else:
|
842 |
+
return data, analysis_visibility, []
|
843 |
+
|
844 |
load_button.click(
|
845 |
+
load_data_interface,
|
846 |
inputs=[design_type_input, factor_names_input, factor_levels_input, y_name_input, data_input],
|
847 |
outputs=[data_output, analysis_row, selected_factors_input]
|
848 |
)
|
|
|
866 |
]
|
867 |
)
|
868 |
|
869 |
+
# Conectar los botones de descarga de tablas
|
870 |
download_excel_button.click(
|
871 |
+
fn=download_all_tables_excel,
|
872 |
inputs=[],
|
873 |
outputs=download_excel_button
|
874 |
)
|
875 |
+
|
876 |
download_word_button.click(
|
877 |
+
fn=exportar_word,
|
878 |
+
inputs=[gr.State()],
|
879 |
outputs=download_word_button
|
880 |
)
|
881 |
|
882 |
# Generar y mostrar los gráficos
|
883 |
+
def generate_plots():
|
884 |
+
if 'rsm' not in globals() or not rsm.all_figures:
|
885 |
+
return None, "No hay gráficos disponibles.", 0, []
|
886 |
+
# Mostrar el primer gráfico
|
887 |
+
return rsm.all_figures[0], f"Gráfico 1 de {len(rsm.all_figures)}", 0, rsm.all_figures
|
888 |
+
|
889 |
plot_button.click(
|
890 |
+
generate_plots,
|
|
|
|
|
|
|
|
|
|
|
891 |
inputs=[],
|
892 |
outputs=[rsm_plot_output, plot_info, current_index_state, all_figures_state]
|
893 |
)
|
894 |
|
895 |
# Navegación de gráficos
|
896 |
+
def navigate(direction, current_index, all_figures):
|
897 |
+
if not all_figures:
|
898 |
+
return None, "No hay gráficos disponibles.", current_index
|
899 |
+
if direction == 'left':
|
900 |
+
new_index = (current_index - 1) % len(all_figures)
|
901 |
+
elif direction == 'right':
|
902 |
+
new_index = (current_index + 1) % len(all_figures)
|
903 |
+
else:
|
904 |
+
new_index = current_index
|
905 |
+
selected_fig = all_figures[new_index]
|
906 |
+
plot_info_text = f"Gráfico {new_index + 1} de {len(all_figures)}"
|
907 |
+
return selected_fig, plot_info_text, new_index
|
908 |
+
|
909 |
left_button.click(
|
910 |
+
navigate,
|
911 |
+
inputs=[gr.Button("left"), current_index_state, all_figures_state],
|
912 |
outputs=[rsm_plot_output, plot_info, current_index_state]
|
913 |
)
|
914 |
+
|
915 |
right_button.click(
|
916 |
+
navigate,
|
917 |
+
inputs=[gr.Button("right"), current_index_state, all_figures_state],
|
918 |
outputs=[rsm_plot_output, plot_info, current_index_state]
|
919 |
)
|
920 |
|
|
|
938 |
1. **Configura el Diseño:**
|
939 |
- Selecciona el tipo de diseño (Box-Behnken o Central Compuesto).
|
940 |
- Ingresa los nombres de los factores separados por comas.
|
941 |
+
- Ingresa los niveles para cada factor separados por comas y cada conjunto de niveles por ';'.
|
942 |
- Especifica el nombre de la variable dependiente.
|
943 |
- Proporciona los datos del experimento en formato CSV.
|
944 |
2. **Cargar Datos:**
|
945 |
- Haz clic en 'Cargar Datos' para cargar y visualizar los datos.
|
946 |
+
3. **Seleccionar Factores para el Modelo Simplificado:**
|
947 |
+
- Marca los factores que deseas incluir en el modelo simplificado.
|
948 |
+
4. **Ajustar Modelo y Optimizar:**
|
949 |
- Haz clic en 'Ajustar Modelo y Optimizar' para ajustar los modelos y obtener los resultados.
|
950 |
+
5. **Generar y Navegar Gráficos:**
|
951 |
- Haz clic en 'Generar Gráficos' para crear las superficies de respuesta.
|
952 |
- Navega entre los gráficos usando los botones '<' y '>'.
|
953 |
+
- Descarga el gráfico actual en PNG o todos los gráficos en un archivo ZIP.
|
954 |
+
6. **Descargar Tablas:**
|
955 |
- Descarga todas las tablas generadas en un archivo Excel o Word.
|
956 |
""")
|
957 |
|
958 |
return demo
|
959 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
960 |
# --- Función Principal ---
|
961 |
|
962 |
def main():
|