C2MV commited on
Commit
32ffd0d
·
verified ·
1 Parent(s): 629ec27

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +232 -145
app.py CHANGED
@@ -11,7 +11,13 @@ import io
11
  import zipfile
12
  import tempfile
13
  from datetime import datetime
 
 
 
 
 
14
 
 
15
  class RSM_BoxBehnken:
16
  def __init__(self, data, x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels):
17
  """
@@ -296,7 +302,7 @@ class RSM_BoxBehnken:
296
 
297
  def get_simplified_equation(self):
298
  """
299
- Imprime la ecuación del modelo simplificado.
300
  """
301
  if self.model_simplified is None:
302
  print("Error: Ajusta el modelo simplificado primero.")
@@ -532,7 +538,62 @@ class RSM_BoxBehnken:
532
 
533
  return temp_path
534
 
535
- # --- Funciones para la interfaz de Gradio ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
 
537
  def load_data(x1_name, x2_name, x3_name, y_name, x1_levels_str, x2_levels_str, x3_levels_str, data_str):
538
  """
@@ -559,7 +620,7 @@ def load_data(x1_name, x2_name, x3_name, y_name, x1_levels_str, x2_levels_str, x
559
  rsm = RSM_BoxBehnken(data, x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels)
560
 
561
  return data.round(3), x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels, gr.update(visible=True)
562
-
563
  except Exception as e:
564
  # Mostrar mensaje de error
565
  error_message = f"Error al cargar los datos: {str(e)}"
@@ -658,8 +719,8 @@ def download_all_plots_zip():
658
  zip_path = rsm.save_figures_to_zip()
659
  if zip_path:
660
  filename = f"Graficos_RSM_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
661
- # Renombrar el archivo temporal al nombre deseado
662
- return (zip_path, filename)
663
  return None
664
 
665
  def download_all_tables_excel():
@@ -671,26 +732,36 @@ def download_all_tables_excel():
671
  excel_path = rsm.save_tables_to_excel()
672
  if excel_path:
673
  filename = f"Tablas_RSM_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
674
- # Renombrar el archivo temporal al nombre deseado
675
- return (excel_path, filename)
 
 
 
 
 
 
 
 
 
676
  return None
677
 
678
  # --- Crear la interfaz de Gradio ---
679
 
680
- with gr.Blocks() as demo:
681
- gr.Markdown("# Optimización de la producción de AIA usando RSM Box-Behnken")
682
-
683
- with gr.Row():
684
- with gr.Column():
685
- gr.Markdown("## Configuración del Diseño")
686
- x1_name_input = gr.Textbox(label="Nombre de la Variable X1 (ej. Glucosa)", value="Glucosa")
687
- x2_name_input = gr.Textbox(label="Nombre de la Variable X2 (ej. Extracto de Levadura)", value="Extracto_de_Levadura")
688
- x3_name_input = gr.Textbox(label="Nombre de la Variable X3 (ej. Triptófano)", value="Triptofano")
689
- y_name_input = gr.Textbox(label="Nombre de la Variable Dependiente (ej. AIA (ppm))", value="AIA_ppm")
690
- x1_levels_input = gr.Textbox(label="Niveles de X1 (separados por comas)", value="1, 3.5, 5.5")
691
- x2_levels_input = gr.Textbox(label="Niveles de X2 (separados por comas)", value="0.03, 0.2, 0.3")
692
- x3_levels_input = gr.Textbox(label="Niveles de X3 (separados por comas)", value="0.4, 0.65, 0.9")
693
- data_input = gr.Textbox(label="Datos del Experimento (formato CSV)", lines=10, value="""1,-1,-1,0,166.594
 
694
  2,1,-1,0,177.557
695
  3,-1,1,0,127.261
696
  4,1,1,0,147.573
@@ -705,130 +776,146 @@ with gr.Blocks() as demo:
705
  13,0,0,0,278.951
706
  14,0,0,0,297.238
707
  15,0,0,0,280.896""")
708
- load_button = gr.Button("Cargar Datos")
 
 
 
 
709
 
710
- with gr.Column():
711
- gr.Markdown("## Datos Cargados")
712
- data_output = gr.Dataframe(label="Tabla de Datos", interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
 
714
- # Sección de análisis visible solo después de cargar los datos
715
- with gr.Row(visible=False) as analysis_row:
716
- with gr.Column():
717
- fit_button = gr.Button("Ajustar Modelo y Optimizar")
718
- gr.Markdown("**Modelo Completo**")
719
- model_completo_output = gr.HTML()
720
- pareto_completo_output = gr.Plot()
721
- gr.Markdown("**Modelo Simplificado**")
722
- model_simplificado_output = gr.HTML()
723
- pareto_simplificado_output = gr.Plot()
724
- gr.Markdown("**Ecuación del Modelo Simplificado**")
725
- equation_output = gr.HTML()
726
- optimization_table_output = gr.Dataframe(label="Tabla de Optimización", interactive=False)
727
- prediction_table_output = gr.Dataframe(label="Tabla de Predicciones", interactive=False)
728
- contribution_table_output = gr.Dataframe(label="Tabla de % de Contribución", interactive=False)
729
- anova_table_output = gr.Dataframe(label="Tabla ANOVA Detallada", interactive=False)
730
- gr.Markdown("## Descargar Todas las Tablas")
731
- download_excel_button = gr.DownloadButton("Descargar Tablas en Excel")
732
 
733
- with gr.Column():
734
- gr.Markdown("## Generar Gráficos de Superficie de Respuesta")
735
- fixed_variable_input = gr.Dropdown(label="Variable Fija", choices=["Glucosa", "Extracto_de_Levadura", "Triptofano"], value="Glucosa")
736
- fixed_level_input = gr.Slider(label="Nivel de Variable Fija", minimum=-1, maximum=1, step=0.01, value=0.0)
737
- plot_button = gr.Button("Generar Gráficos")
738
- with gr.Row():
739
- left_button = gr.Button("<")
740
- right_button = gr.Button(">")
741
- rsm_plot_output = gr.Plot()
742
- plot_info = gr.Textbox(label="Información del Gráfico", value="Gráfico 1 de 9", interactive=False)
743
- with gr.Row():
744
- download_plot_button = gr.DownloadButton("Descargar Gráfico Actual (PNG)")
745
- download_all_plots_button = gr.DownloadButton("Descargar Todos los Gráficos (ZIP)")
746
- current_index_state = gr.State(0) # Estado para el índice actual
747
- all_figures_state = gr.State([]) # Estado para todas las figuras
748
-
749
- # Cargar datos
750
- load_button.click(
751
- load_data,
752
- inputs=[x1_name_input, x2_name_input, x3_name_input, y_name_input, x1_levels_input, x2_levels_input, x3_levels_input, data_input],
753
- outputs=[data_output, x1_name_input, x2_name_input, x3_name_input, y_name_input, x1_levels_input, x2_levels_input, x3_levels_input, analysis_row]
754
- )
755
-
756
- # Ajustar modelo y optimizar
757
- fit_button.click(
758
- fit_and_optimize_model,
759
- inputs=[],
760
- outputs=[
761
- model_completo_output,
762
- pareto_completo_output,
763
- model_simplificado_output,
764
- pareto_simplificado_output,
765
- equation_output,
766
- optimization_table_output,
767
- prediction_table_output,
768
- contribution_table_output,
769
- anova_table_output,
770
- download_all_plots_button, # Ruta del ZIP de gráficos
771
- download_excel_button # Ruta del Excel de tablas
772
- ]
773
- )
774
-
775
- # Generar y mostrar los gráficos
776
- plot_button.click(
777
- lambda fixed_var, fixed_lvl: (
778
- rsm.plot_rsm_individual(fixed_var, fixed_lvl),
779
- f"Gráfico 1 de {len(rsm.all_figures)}" if rsm.all_figures else "No hay gráficos disponibles.",
780
- 0,
781
- rsm.all_figures # Actualizar el estado de todas las figuras
782
- ),
783
- inputs=[fixed_variable_input, fixed_level_input],
784
- outputs=[rsm_plot_output, plot_info, current_index_state, all_figures_state]
785
- )
786
-
787
- # Navegación de gráficos
788
- left_button.click(
789
- lambda current_index, all_figures: navigate_plot('left', current_index, all_figures),
790
- inputs=[current_index_state, all_figures_state],
791
- outputs=[rsm_plot_output, plot_info, current_index_state]
792
- )
793
- right_button.click(
794
- lambda current_index, all_figures: navigate_plot('right', current_index, all_figures),
795
- inputs=[current_index_state, all_figures_state],
796
- outputs=[rsm_plot_output, plot_info, current_index_state]
797
- )
798
-
799
- # Descargar gráfico actual
800
- download_plot_button.click(
801
- download_current_plot,
802
- inputs=[all_figures_state, current_index_state],
803
- outputs=download_plot_button
804
- )
805
-
806
- # Descargar todos los gráficos en ZIP
807
- download_all_plots_button.click(
808
- download_all_plots_zip,
809
- inputs=[],
810
- outputs=download_all_plots_button
811
- )
812
-
813
- # Descargar todas las tablas en Excel
814
- download_excel_button.click(
815
- download_all_tables_excel,
816
- inputs=[],
817
- outputs=download_excel_button
818
- )
819
-
820
- # Ejemplo de uso
821
- gr.Markdown("## Ejemplo de uso")
822
- gr.Markdown("""
823
- 1. Introduce los nombres de las variables y sus niveles en las cajas de texto correspondientes.
824
- 2. Copia y pega los datos del experimento en la caja de texto 'Datos del Experimento'.
825
- 3. Haz clic en 'Cargar Datos' para cargar los datos en la tabla.
826
- 4. Haz clic en 'Ajustar Modelo y Optimizar' para ajustar el modelo y encontrar los niveles óptimos de los factores.
827
- 5. Selecciona una variable fija y su nivel en los controles deslizantes.
828
- 6. Haz clic en 'Generar Gráficos' para generar los gráficos de superficie de respuesta.
829
- 7. Navega entre los gráficos usando los botones '<' y '>'.
830
- 8. Descarga el gráfico actual en PNG o descarga todos los gráficos en un ZIP.
831
- 9. Descarga todas las tablas en un archivo Excel con el botón correspondiente.
832
- """)
833
-
834
- demo.launch()
 
11
  import zipfile
12
  import tempfile
13
  from datetime import datetime
14
+ import docx
15
+ from docx.shared import Inches, Pt
16
+ from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
17
+ from matplotlib.colors import to_hex
18
+ import os
19
 
20
+ # --- Clase RSM_BoxBehnken ---
21
  class RSM_BoxBehnken:
22
  def __init__(self, data, x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels):
23
  """
 
302
 
303
  def get_simplified_equation(self):
304
  """
305
+ Retorna la ecuación del modelo simplificado como una cadena de texto.
306
  """
307
  if self.model_simplified is None:
308
  print("Error: Ajusta el modelo simplificado primero.")
 
538
 
539
  return temp_path
540
 
541
+ def export_tables_to_word(self, tables_dict):
542
+ """
543
+ Exporta las tablas proporcionadas a un documento de Word.
544
+ """
545
+ if not tables_dict:
546
+ return None
547
+
548
+ doc = docx.Document()
549
+
550
+ # Configurar estilo de fuente
551
+ style = doc.styles['Normal']
552
+ font = style.font
553
+ font.name = 'Times New Roman'
554
+ font.size = Pt(12)
555
+
556
+ # Título del informe
557
+ titulo = doc.add_heading('Informe de Optimización de Producción de AIA', 0)
558
+ titulo.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
559
+
560
+ doc.add_paragraph(f"Fecha: {datetime.now().strftime('%d/%m/%Y %H:%M')}").alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
561
+
562
+ doc.add_paragraph('\n') # Espacio
563
+
564
+ for sheet_name, table in tables_dict.items():
565
+ # Añadir título de la tabla
566
+ doc.add_heading(sheet_name, level=1)
567
+
568
+ if table.empty:
569
+ doc.add_paragraph("No hay datos disponibles para esta tabla.")
570
+ continue
571
+
572
+ # Añadir tabla al documento
573
+ table_doc = doc.add_table(rows=1, cols=len(table.columns))
574
+ table_doc.style = 'Light List Accent 1'
575
+
576
+ # Añadir encabezados
577
+ hdr_cells = table_doc.rows[0].cells
578
+ for idx, col_name in enumerate(table.columns):
579
+ hdr_cells[idx].text = col_name
580
+
581
+ # Añadir filas de datos
582
+ for _, row in table.iterrows():
583
+ row_cells = table_doc.add_row().cells
584
+ for idx, item in enumerate(row):
585
+ row_cells[idx].text = str(item)
586
+
587
+ doc.add_paragraph('\n') # Espacio entre tablas
588
+
589
+ # Guardar el documento en un archivo temporal
590
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp:
591
+ doc.save(tmp.name)
592
+ tmp_path = tmp.name
593
+
594
+ return tmp_path
595
+
596
+ # --- Funciones para la Interfaz de Gradio ---
597
 
598
  def load_data(x1_name, x2_name, x3_name, y_name, x1_levels_str, x2_levels_str, x3_levels_str, data_str):
599
  """
 
620
  rsm = RSM_BoxBehnken(data, x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels)
621
 
622
  return data.round(3), x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels, gr.update(visible=True)
623
+
624
  except Exception as e:
625
  # Mostrar mensaje de error
626
  error_message = f"Error al cargar los datos: {str(e)}"
 
719
  zip_path = rsm.save_figures_to_zip()
720
  if zip_path:
721
  filename = f"Graficos_RSM_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
722
+ # Gradio no permite renombrar directamente, por lo que retornamos la ruta del archivo
723
+ return zip_path
724
  return None
725
 
726
  def download_all_tables_excel():
 
732
  excel_path = rsm.save_tables_to_excel()
733
  if excel_path:
734
  filename = f"Tablas_RSM_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
735
+ # Gradio no permite renombrar directamente, por lo que retornamos la ruta del archivo
736
+ return excel_path
737
+ return None
738
+
739
+ def exportar_word(rsm_instance, tables_dict):
740
+ """
741
+ Función para exportar las tablas a un documento de Word.
742
+ """
743
+ word_path = rsm_instance.export_tables_to_word(tables_dict)
744
+ if word_path and os.path.exists(word_path):
745
+ return word_path
746
  return None
747
 
748
  # --- Crear la interfaz de Gradio ---
749
 
750
+ def create_gradio_interface():
751
+ with gr.Blocks() as demo:
752
+ gr.Markdown("# Optimización de la producción de AIA usando RSM Box-Behnken")
753
+
754
+ with gr.Row():
755
+ with gr.Column():
756
+ gr.Markdown("## Configuración del Diseño")
757
+ x1_name_input = gr.Textbox(label="Nombre de la Variable X1 (ej. Glucosa)", value="Glucosa")
758
+ x2_name_input = gr.Textbox(label="Nombre de la Variable X2 (ej. Extracto de Levadura)", value="Extracto_de_Levadura")
759
+ x3_name_input = gr.Textbox(label="Nombre de la Variable X3 (ej. Triptófano)", value="Triptofano")
760
+ y_name_input = gr.Textbox(label="Nombre de la Variable Dependiente (ej. AIA (ppm))", value="AIA_ppm")
761
+ x1_levels_input = gr.Textbox(label="Niveles de X1 (separados por comas)", value="1, 3.5, 5.5")
762
+ x2_levels_input = gr.Textbox(label="Niveles de X2 (separados por comas)", value="0.03, 0.2, 0.3")
763
+ x3_levels_input = gr.Textbox(label="Niveles de X3 (separados por comas)", value="0.4, 0.65, 0.9")
764
+ data_input = gr.Textbox(label="Datos del Experimento (formato CSV)", lines=10, value="""1,-1,-1,0,166.594
765
  2,1,-1,0,177.557
766
  3,-1,1,0,127.261
767
  4,1,1,0,147.573
 
776
  13,0,0,0,278.951
777
  14,0,0,0,297.238
778
  15,0,0,0,280.896""")
779
+ load_button = gr.Button("Cargar Datos")
780
+
781
+ with gr.Column():
782
+ gr.Markdown("## Datos Cargados")
783
+ data_output = gr.Dataframe(label="Tabla de Datos", interactive=False)
784
 
785
+ # Sección de análisis visible solo después de cargar los datos
786
+ with gr.Row(visible=False) as analysis_row:
787
+ with gr.Column():
788
+ fit_button = gr.Button("Ajustar Modelo y Optimizar")
789
+ gr.Markdown("**Modelo Completo**")
790
+ model_completo_output = gr.HTML()
791
+ pareto_completo_output = gr.Plot()
792
+ gr.Markdown("**Modelo Simplificado**")
793
+ model_simplificado_output = gr.HTML()
794
+ pareto_simplificado_output = gr.Plot()
795
+ gr.Markdown("**Ecuación del Modelo Simplificado**")
796
+ equation_output = gr.HTML()
797
+ optimization_table_output = gr.Dataframe(label="Tabla de Optimización", interactive=False)
798
+ prediction_table_output = gr.Dataframe(label="Tabla de Predicciones", interactive=False)
799
+ contribution_table_output = gr.Dataframe(label="Tabla de % de Contribución", interactive=False)
800
+ anova_table_output = gr.Dataframe(label="Tabla ANOVA Detallada", interactive=False)
801
+ gr.Markdown("## Descargar Todas las Tablas")
802
+ download_excel_button = gr.DownloadButton("Descargar Tablas en Excel")
803
+ download_word_button = gr.DownloadButton("Descargar Tablas en Word")
804
+
805
+ with gr.Column():
806
+ gr.Markdown("## Generar Gráficos de Superficie de Respuesta")
807
+ fixed_variable_input = gr.Dropdown(label="Variable Fija", choices=["Glucosa", "Extracto_de_Levadura", "Triptofano"], value="Glucosa")
808
+ fixed_level_input = gr.Slider(label="Nivel de Variable Fija", minimum=-1, maximum=1, step=0.01, value=0.0)
809
+ plot_button = gr.Button("Generar Gráficos")
810
+ with gr.Row():
811
+ left_button = gr.Button("<")
812
+ right_button = gr.Button(">")
813
+ rsm_plot_output = gr.Plot()
814
+ plot_info = gr.Textbox(label="Información del Gráfico", value="Gráfico 1 de 9", interactive=False)
815
+ with gr.Row():
816
+ download_plot_button = gr.DownloadButton("Descargar Gráfico Actual (PNG)")
817
+ download_all_plots_button = gr.DownloadButton("Descargar Todos los Gráficos (ZIP)")
818
+ current_index_state = gr.State(0) # Estado para el índice actual
819
+ all_figures_state = gr.State([]) # Estado para todas las figuras
820
 
821
+ # Cargar datos
822
+ load_button.click(
823
+ load_data,
824
+ inputs=[x1_name_input, x2_name_input, x3_name_input, y_name_input, x1_levels_input, x2_levels_input, x3_levels_input, data_input],
825
+ outputs=[data_output, x1_name_input, x2_name_input, x3_name_input, y_name_input, x1_levels_input, x2_levels_input, x3_levels_input, analysis_row]
826
+ )
 
 
 
 
 
 
 
 
 
 
 
 
827
 
828
+ # Ajustar modelo y optimizar
829
+ fit_button.click(
830
+ fit_and_optimize_model,
831
+ inputs=[],
832
+ outputs=[
833
+ model_completo_output,
834
+ pareto_completo_output,
835
+ model_simplificado_output,
836
+ pareto_simplificado_output,
837
+ equation_output,
838
+ optimization_table_output,
839
+ prediction_table_output,
840
+ contribution_table_output,
841
+ anova_table_output,
842
+ download_all_plots_button, # Ruta del ZIP de gráficos
843
+ download_excel_button # Ruta del Excel de tablas
844
+ ]
845
+ )
846
+
847
+ # Generar y mostrar los gráficos
848
+ plot_button.click(
849
+ lambda fixed_var, fixed_lvl: (
850
+ rsm.plot_rsm_individual(fixed_var, fixed_lvl),
851
+ f"Gráfico 1 de {len(rsm.all_figures)}" if rsm.all_figures else "No hay gráficos disponibles.",
852
+ 0,
853
+ rsm.all_figures # Actualizar el estado de todas las figuras
854
+ ),
855
+ inputs=[fixed_variable_input, fixed_level_input],
856
+ outputs=[rsm_plot_output, plot_info, current_index_state, all_figures_state]
857
+ )
858
+
859
+ # Navegación de gráficos
860
+ left_button.click(
861
+ lambda current_index, all_figures: navigate_plot('left', current_index, all_figures),
862
+ inputs=[current_index_state, all_figures_state],
863
+ outputs=[rsm_plot_output, plot_info, current_index_state]
864
+ )
865
+ right_button.click(
866
+ lambda current_index, all_figures: navigate_plot('right', current_index, all_figures),
867
+ inputs=[current_index_state, all_figures_state],
868
+ outputs=[rsm_plot_output, plot_info, current_index_state]
869
+ )
870
+
871
+ # Descargar gráfico actual
872
+ download_plot_button.click(
873
+ download_current_plot,
874
+ inputs=[all_figures_state, current_index_state],
875
+ outputs=download_plot_button
876
+ )
877
+
878
+ # Descargar todos los gráficos en ZIP
879
+ download_all_plots_button.click(
880
+ download_all_plots_zip,
881
+ inputs=[],
882
+ outputs=download_all_plots_button
883
+ )
884
+
885
+ # Descargar todas las tablas en Excel y Word
886
+ download_excel_button.click(
887
+ fn=lambda: download_all_tables_excel(),
888
+ inputs=[],
889
+ outputs=download_excel_button
890
+ )
891
+
892
+ download_word_button.click(
893
+ fn=lambda: exportar_word(rsm, rsm.get_all_tables()),
894
+ inputs=[],
895
+ outputs=download_word_button
896
+ )
897
+
898
+ # Ejemplo de uso
899
+ gr.Markdown("## Ejemplo de uso")
900
+ gr.Markdown("""
901
+ 1. Introduce los nombres de las variables y sus niveles en las cajas de texto correspondientes.
902
+ 2. Copia y pega los datos del experimento en la caja de texto 'Datos del Experimento'.
903
+ 3. Haz clic en 'Cargar Datos' para cargar los datos en la tabla.
904
+ 4. Haz clic en 'Ajustar Modelo y Optimizar' para ajustar el modelo y encontrar los niveles óptimos de los factores.
905
+ 5. Selecciona una variable fija y su nivel en los controles deslizantes.
906
+ 6. Haz clic en 'Generar Gráficos' para generar los gráficos de superficie de respuesta.
907
+ 7. Navega entre los gráficos usando los botones '<' y '>'.
908
+ 8. Descarga el gráfico actual en PNG o descarga todos los gráficos en un ZIP.
909
+ 9. Descarga todas las tablas en un archivo Excel o Word con los botones correspondientes.
910
+ """)
911
+
912
+ return demo
913
+
914
+ # --- Función Principal ---
915
+
916
+ def main():
917
+ interface = create_gradio_interface()
918
+ interface.launch(share=True)
919
+
920
+ if __name__ == "__main__":
921
+ main()