C2MV commited on
Commit
10fce6d
·
verified ·
1 Parent(s): 3301441

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -96
app.py CHANGED
@@ -69,7 +69,7 @@ class RSM_BoxBehnken:
69
  Ajusta el modelo de segundo orden a los datos, eliminando términos no significativos.
70
  """
71
  formula = f'{self.y_name} ~ {self.x1_name} + {self.x2_name} + ' \
72
- f'I({self.x1_name}**2) + I({self.x2_name}**2) + I({self.x3_name}**2)'
73
  self.model_simplified = smf.ols(formula, data=self.data).fit()
74
  print("\nModelo Simplificado:")
75
  print(self.model_simplified.summary())
@@ -121,7 +121,7 @@ class RSM_BoxBehnken:
121
 
122
  # Determinar las variables que varían y sus niveles naturales
123
  varying_variables = [var for var in [self.x1_name, self.x2_name, self.x3_name] if var != fixed_variable]
124
-
125
  # Establecer los niveles naturales para las variables que varían
126
  x_natural_levels = self.get_levels(varying_variables[0])
127
  y_natural_levels = self.get_levels(varying_variables[1])
@@ -224,10 +224,10 @@ class RSM_BoxBehnken:
224
  Puedes personalizar este método según tus necesidades.
225
  """
226
  units = {
227
- 'Glucosa': 'g/L',
228
- 'Extracto_de_Levadura': 'g/L',
229
- 'Triptofano': 'g/L',
230
- 'AIA_ppm': 'ppm'
231
  }
232
  return units.get(variable_name, '')
233
 
@@ -242,11 +242,11 @@ class RSM_BoxBehnken:
242
 
243
  self.all_figures = [] # Resetear la lista de figuras
244
 
245
- # Niveles naturales para graficar
246
  levels_to_plot_natural = {
247
- self.x1_name: self.x1_levels,
248
- self.x2_name: self.x2_levels,
249
- self.x3_name: self.x3_levels
250
  }
251
 
252
  # Generar y almacenar gráficos individuales
@@ -361,7 +361,7 @@ class RSM_BoxBehnken:
361
  'Suma de Cuadrados': [],
362
  '% Contribución': []
363
  })
364
-
365
  # Calcular porcentaje de contribución para cada factor
366
  for index, row in anova_table.iterrows():
367
  if index != 'Residual':
@@ -372,7 +372,7 @@ class RSM_BoxBehnken:
372
  factor_name = f'{self.x2_name}^2'
373
  elif factor_name == f'I({self.x3_name} ** 2)':
374
  factor_name = f'{self.x3_name}^2'
375
-
376
  ss_factor = row['sum_sq']
377
  contribution_percentage = (ss_factor / ss_total) * 100
378
 
@@ -433,7 +433,7 @@ class RSM_BoxBehnken:
433
  # 10. Cuadrados medios
434
  ms_regression = ss_regression / df_regression
435
  ms_residual = ss_residual / df_residual
436
- ms_lack_of_fit = ss_lack_of_fit / df_lack_of_fit if not np.isnan(ss_lack_of_fit) else np.nan
437
  ms_pure_error = ss_pure_error / df_pure_error if not np.isnan(ss_pure_error) else np.nan
438
 
439
  # 11. Estadístico F y valor p para la falta de ajuste
@@ -449,7 +449,7 @@ class RSM_BoxBehnken:
449
  'F': [np.nan, np.nan, f_lack_of_fit, np.nan, np.nan],
450
  'Valor p': [np.nan, np.nan, p_lack_of_fit, np.nan, np.nan]
451
  })
452
-
453
  # Calcular la suma de cuadrados y grados de libertad para la curvatura
454
  ss_curvature = anova_reduced['sum_sq'][f'I({self.x1_name} ** 2)'] + anova_reduced['sum_sq'][f'I({self.x2_name} ** 2)'] + anova_reduced['sum_sq'][f'I({self.x3_name} ** 2)']
455
  df_curvature = 3
@@ -459,7 +459,7 @@ class RSM_BoxBehnken:
459
 
460
  # Reorganizar las filas para que la curvatura aparezca después de la regresión
461
  detailed_anova_table = detailed_anova_table.reindex([0, 5, 1, 2, 3, 4])
462
-
463
  # Resetear el índice para que sea consecutivo
464
  detailed_anova_table = detailed_anova_table.reset_index(drop=True)
465
 
@@ -554,7 +554,7 @@ class RSM_BoxBehnken:
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
@@ -595,37 +595,48 @@ class RSM_BoxBehnken:
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
  """
600
  Carga los datos del diseño Box-Behnken desde cajas de texto y crea la instancia de RSM_BoxBehnken.
601
  """
602
  try:
603
- # Convertir los niveles a listas de números
604
- x1_levels = [float(x.strip()) for x in x1_levels_str.split(',')]
605
- x2_levels = [float(x.strip()) for x in x2_levels_str.split(',')]
606
- x3_levels = [float(x.strip()) for x in x3_levels_str.split(',')]
 
 
 
 
 
 
 
 
 
 
 
607
 
608
- # Crear DataFrame a partir de la cadena de datos
609
- data_list = [row.split(',') for row in data_str.strip().split('\n')]
610
- column_names = ['Exp.', x1_name, x2_name, x3_name, y_name]
611
- data = pd.DataFrame(data_list, columns=column_names)
612
- data = data.apply(pd.to_numeric, errors='coerce') # Convertir a numérico
 
 
613
 
614
- # Validar que el DataFrame tenga las columnas correctas
615
- if not all(col in data.columns for col in column_names):
616
- raise ValueError("El formato de los datos no es correcto.")
617
 
618
  # Crear la instancia de RSM_BoxBehnken
619
  global rsm
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)}"
627
  print(error_message)
628
- return None, "", "", "", "", [], [], [], gr.update(visible=False)
 
629
 
630
  def fit_and_optimize_model():
631
  if 'rsm' not in globals():
@@ -639,14 +650,14 @@ def fit_and_optimize_model():
639
  prediction_table = rsm.generate_prediction_table()
640
  contribution_table = rsm.calculate_contribution_percentage()
641
  anova_table = rsm.calculate_detailed_anova()
642
-
643
- # Generar todas las figuras y almacenarlas
644
  rsm.generate_all_plots()
645
-
646
  # Formatear la ecuación para que se vea mejor en Markdown
647
  equation_formatted = equation.replace(" + ", "<br>+ ").replace(" ** ", "^").replace("*", " × ")
648
  equation_formatted = f"### Ecuación del Modelo Simplificado:<br>{equation_formatted}"
649
-
650
  # Guardar las tablas en Excel temporal
651
  excel_path = rsm.save_tables_to_excel()
652
 
@@ -658,7 +669,7 @@ def fit_and_optimize_model():
658
  pareto_completo,
659
  model_simplificado.summary().as_html(),
660
  pareto_simplificado,
661
- equation_formatted,
662
  optimization_table,
663
  prediction_table,
664
  contribution_table,
@@ -680,17 +691,17 @@ def navigate_plot(direction, current_index, all_figures):
680
  """
681
  if not all_figures:
682
  return None, "No hay gráficos disponibles.", current_index
683
-
684
  if direction == 'left':
685
  new_index = (current_index - 1) % len(all_figures)
686
  elif direction == 'right':
687
  new_index = (current_index + 1) % len(all_figures)
688
  else:
689
  new_index = current_index
690
-
691
  selected_fig = all_figures[new_index]
692
  plot_info_text = f"Gráfico {new_index + 1} de {len(all_figures)}"
693
-
694
  return selected_fig, plot_info_text, new_index
695
 
696
  def download_current_plot(all_figures, current_index):
@@ -702,12 +713,12 @@ def download_current_plot(all_figures, current_index):
702
  fig = all_figures[current_index]
703
  img_bytes = rsm.save_fig_to_bytes(fig)
704
  filename = f"Grafico_RSM_{current_index + 1}.png"
705
-
706
  # Crear un archivo temporal
707
  with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
708
  temp_file.write(img_bytes)
709
  temp_path = temp_file.name
710
-
711
  return temp_path # Retornar solo la ruta
712
 
713
  def download_all_plots_zip():
@@ -749,39 +760,19 @@ def exportar_word(rsm_instance, tables_dict):
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
768
- 5,-1,0,-1,188.883
769
- 6,1,0,-1,224.527
770
- 7,-1,0,1,190.238
771
- 8,1,0,1,226.483
772
- 9,0,-1,-1,195.550
773
- 10,0,1,-1,149.493
774
- 11,0,-1,1,187.683
775
- 12,0,1,1,148.621
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():
@@ -801,11 +792,11 @@ def create_gradio_interface():
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("<")
@@ -817,14 +808,14 @@ def create_gradio_interface():
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,
@@ -843,7 +834,7 @@ def create_gradio_interface():
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: (
@@ -855,7 +846,7 @@ def create_gradio_interface():
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),
@@ -867,46 +858,43 @@ def create_gradio_interface():
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
@@ -918,4 +906,4 @@ def main():
918
  interface.launch(share=True)
919
 
920
  if __name__ == "__main__":
921
- main()
 
69
  Ajusta el modelo de segundo orden a los datos, eliminando términos no significativos.
70
  """
71
  formula = f'{self.y_name} ~ {self.x1_name} + {self.x2_name} + ' \
72
+ f'I({self.x1_name}**2) + I({self.x2_name}**2) + I({self.x3_name}**2)' # Adjusted formula to include x3^2
73
  self.model_simplified = smf.ols(formula, data=self.data).fit()
74
  print("\nModelo Simplificado:")
75
  print(self.model_simplified.summary())
 
121
 
122
  # Determinar las variables que varían y sus niveles naturales
123
  varying_variables = [var for var in [self.x1_name, self.x2_name, self.x3_name] if var != fixed_variable]
124
+
125
  # Establecer los niveles naturales para las variables que varían
126
  x_natural_levels = self.get_levels(varying_variables[0])
127
  y_natural_levels = self.get_levels(varying_variables[1])
 
224
  Puedes personalizar este método según tus necesidades.
225
  """
226
  units = {
227
+ 'Glucosa_g_L': 'g/L',
228
+ 'Proteina_Pescado_g_L': 'g/L',
229
+ 'Sulfato_Manganeso_g_L': 'g/L',
230
+ 'Abs_600nm': '' # No units for Absorbance
231
  }
232
  return units.get(variable_name, '')
233
 
 
242
 
243
  self.all_figures = [] # Resetear la lista de figuras
244
 
245
+ # Niveles naturales para graficar - Using levels from the data context, not Box-Behnken design levels.
246
  levels_to_plot_natural = {
247
+ self.x1_name: sorted(list(set(self.data[self.x1_name]))), # Using unique values from data
248
+ self.x2_name: sorted(list(set(self.data[self.x2_name]))), # Using unique values from data
249
+ self.x3_name: sorted(list(set(self.data[self.x3_name]))) # Using unique values from data
250
  }
251
 
252
  # Generar y almacenar gráficos individuales
 
361
  'Suma de Cuadrados': [],
362
  '% Contribución': []
363
  })
364
+
365
  # Calcular porcentaje de contribución para cada factor
366
  for index, row in anova_table.iterrows():
367
  if index != 'Residual':
 
372
  factor_name = f'{self.x2_name}^2'
373
  elif factor_name == f'I({self.x3_name} ** 2)':
374
  factor_name = f'{self.x3_name}^2'
375
+
376
  ss_factor = row['sum_sq']
377
  contribution_percentage = (ss_factor / ss_total) * 100
378
 
 
433
  # 10. Cuadrados medios
434
  ms_regression = ss_regression / df_regression
435
  ms_residual = ss_residual / df_residual
436
+ ms_lack_of_fit = ms_lack_of_fit / df_lack_of_fit if not np.isnan(ss_lack_of_fit) else np.nan
437
  ms_pure_error = ss_pure_error / df_pure_error if not np.isnan(ss_pure_error) else np.nan
438
 
439
  # 11. Estadístico F y valor p para la falta de ajuste
 
449
  'F': [np.nan, np.nan, f_lack_of_fit, np.nan, np.nan],
450
  'Valor p': [np.nan, np.nan, p_lack_of_fit, np.nan, np.nan]
451
  })
452
+
453
  # Calcular la suma de cuadrados y grados de libertad para la curvatura
454
  ss_curvature = anova_reduced['sum_sq'][f'I({self.x1_name} ** 2)'] + anova_reduced['sum_sq'][f'I({self.x2_name} ** 2)'] + anova_reduced['sum_sq'][f'I({self.x3_name} ** 2)']
455
  df_curvature = 3
 
459
 
460
  # Reorganizar las filas para que la curvatura aparezca después de la regresión
461
  detailed_anova_table = detailed_anova_table.reindex([0, 5, 1, 2, 3, 4])
462
+
463
  # Resetear el índice para que sea consecutivo
464
  detailed_anova_table = detailed_anova_table.reset_index(drop=True)
465
 
 
554
  font.size = Pt(12)
555
 
556
  # Título del informe
557
+ titulo = doc.add_heading('Informe de Optimización de Producción de Absorbancia', 0) # Changed Title
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
 
595
 
596
  # --- Funciones para la Interfaz de Gradio ---
597
 
598
+ def load_data(data_str): # Modified load_data to only take data_str
599
  """
600
  Carga los datos del diseño Box-Behnken desde cajas de texto y crea la instancia de RSM_BoxBehnken.
601
  """
602
  try:
603
+ # Use the data dictionary directly
604
+ data_dict = {
605
+ 'Tratamiento': ['T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10', 'T11', 'T12', 'T13', 'T14', 'T15'] * 3,
606
+ 'Tiempo_fermentacion_h': [16] * 15 + [23] * 15 + [40] * 15,
607
+ 'pH': [6.02, 5.39, 6.27, 4.82, 6.25, 4.87, 4.76, 4.68, 4.64, 6.35, 4.67, 6.43, 4.58, 4.60, 6.96,
608
+ 5.17, 5.95, 6.90, 5.50, 5.08, 4.95, 5.41, 5.52, 4.98, 7.10, 5.36, 6.91, 5.21, 4.66, 7.10,
609
+ 5.42, 5.60, 7.36, 5.36, 4.66, 4.93, 5.18, 5.26, 4.92, 7.28, 5.26, 6.84, 5.19, 4.58, 7.07],
610
+ 'Abs_600nm': [1.576, 1.474, 1.293, 1.446, 1.537, 1.415, 1.481, 1.419, 1.321, 1.224, 1.459, 0.345, 1.279, 1.181, 0.662,
611
+ 1.760, 1.690, 1.485, 1.658, 1.728, 1.594, 1.673, 1.607, 1.531, 1.424, 1.595, 0.344, 1.477, 1.257, 0.660,
612
+ 1.932, 1.780, 1.689, 1.876, 1.885, 1.824, 1.913, 1.810, 1.852, 1.694, 1.831, 0.347, 1.752, 1.367, 0.656],
613
+ 'Glucosa_g_L': [5,10,0,5,10,5,10,5,10,0,5,0,5,5,0] * 3,
614
+ 'Proteina_Pescado_g_L': [1.4,1.4,3.2,3.2,3.2,3.2,3.2,5,5,5,5,0,5,5,0] * 3,
615
+ 'Sulfato_Manganeso_g_L': [0.75,0.5,0.75,0.5,0.75,0.5,0.75,0.5,0.25,0.75,0.5,0.25,0.5,0.25,0.5] * 3
616
+ }
617
+ data = pd.DataFrame(data_dict)
618
 
619
+ x1_name = "Glucosa_g_L"
620
+ x2_name = "Proteina_Pescado_g_L"
621
+ x3_name = "Sulfato_Manganeso_g_L"
622
+ y_name = "Abs_600nm"
623
+ x1_levels = sorted(list(set(data[x1_name]))) # Levels from data
624
+ x2_levels = sorted(list(set(data[x2_name]))) # Levels from data
625
+ x3_levels = sorted(list(set(data[x3_name]))) # Levels from data
626
 
 
 
 
627
 
628
  # Crear la instancia de RSM_BoxBehnken
629
  global rsm
630
  rsm = RSM_BoxBehnken(data, x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels)
631
 
632
+ return data.round(3), gr.update(visible=True) # Removed other outputs, only return data_output and analysis_row
633
+
634
  except Exception as e:
635
  # Mostrar mensaje de error
636
  error_message = f"Error al cargar los datos: {str(e)}"
637
  print(error_message)
638
+ return None, gr.update(visible=False) # Removed other outputs, only return data_output and analysis_row
639
+
640
 
641
  def fit_and_optimize_model():
642
  if 'rsm' not in globals():
 
650
  prediction_table = rsm.generate_prediction_table()
651
  contribution_table = rsm.calculate_contribution_percentage()
652
  anova_table = rsm.calculate_detailed_anova()
653
+
654
+ # Generar todas las figuras and store them in rsm.all_figures
655
  rsm.generate_all_plots()
656
+
657
  # Formatear la ecuación para que se vea mejor en Markdown
658
  equation_formatted = equation.replace(" + ", "<br>+ ").replace(" ** ", "^").replace("*", " × ")
659
  equation_formatted = f"### Ecuación del Modelo Simplificado:<br>{equation_formatted}"
660
+
661
  # Guardar las tablas en Excel temporal
662
  excel_path = rsm.save_tables_to_excel()
663
 
 
669
  pareto_completo,
670
  model_simplificado.summary().as_html(),
671
  pareto_simplificado,
672
+ equation_output,
673
  optimization_table,
674
  prediction_table,
675
  contribution_table,
 
691
  """
692
  if not all_figures:
693
  return None, "No hay gráficos disponibles.", current_index
694
+
695
  if direction == 'left':
696
  new_index = (current_index - 1) % len(all_figures)
697
  elif direction == 'right':
698
  new_index = (current_index + 1) % len(all_figures)
699
  else:
700
  new_index = current_index
701
+
702
  selected_fig = all_figures[new_index]
703
  plot_info_text = f"Gráfico {new_index + 1} de {len(all_figures)}"
704
+
705
  return selected_fig, plot_info_text, new_index
706
 
707
  def download_current_plot(all_figures, current_index):
 
713
  fig = all_figures[current_index]
714
  img_bytes = rsm.save_fig_to_bytes(fig)
715
  filename = f"Grafico_RSM_{current_index + 1}.png"
716
+
717
  # Crear un archivo temporal
718
  with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
719
  temp_file.write(img_bytes)
720
  temp_path = temp_file.name
721
+
722
  return temp_path # Retornar solo la ruta
723
 
724
  def download_all_plots_zip():
 
760
 
761
  def create_gradio_interface():
762
  with gr.Blocks() as demo:
763
+ gr.Markdown("# Optimización de la Absorbancia usando RSM") # Changed Title
764
+
765
  with gr.Row():
766
  with gr.Column():
767
+ gr.Markdown("## Configuración del Análisis") # Changed Section Title
768
+ # Removed input boxes for variable names and levels
769
+ data_input = gr.Textbox(label="Datos del Experimento (formato CSV - Ignored, Data is Hardcoded)", lines=5, interactive=False, value="Data is pre-loaded, ignore input.") # Adjusted Textbox
770
+ load_button = gr.Button("Cargar Datos") # Keep load button for triggering data load but input is ignored
771
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
772
  with gr.Column():
773
  gr.Markdown("## Datos Cargados")
774
  data_output = gr.Dataframe(label="Tabla de Datos", interactive=False)
775
+
776
  # Sección de análisis visible solo después de cargar los datos
777
  with gr.Row(visible=False) as analysis_row:
778
  with gr.Column():
 
792
  gr.Markdown("## Descargar Todas las Tablas")
793
  download_excel_button = gr.DownloadButton("Descargar Tablas en Excel")
794
  download_word_button = gr.DownloadButton("Descargar Tablas en Word")
795
+
796
  with gr.Column():
797
  gr.Markdown("## Generar Gráficos de Superficie de Respuesta")
798
+ fixed_variable_input = gr.Dropdown(label="Variable Fija", choices=["Glucosa_g_L", "Proteina_Pescado_g_L", "Sulfato_Manganeso_g_L"], value="Glucosa_g_L") # Updated choices
799
+ fixed_level_input = gr.Slider(label="Nivel de Variable Fija (Natural Units)", minimum=0, maximum=10, step=0.1, value=5.0) # Updated Slider
800
  plot_button = gr.Button("Generar Gráficos")
801
  with gr.Row():
802
  left_button = gr.Button("<")
 
808
  download_all_plots_button = gr.DownloadButton("Descargar Todos los Gráficos (ZIP)")
809
  current_index_state = gr.State(0) # Estado para el índice actual
810
  all_figures_state = gr.State([]) # Estado para todas las figuras
811
+
812
+ # Cargar datos - Modified load_button click to only take data_input (which is ignored)
813
  load_button.click(
814
  load_data,
815
+ inputs=[data_input], # Only data_input is now input
816
+ outputs=[data_output, analysis_row] # Removed other outputs, only return data_output and analysis_row
817
  )
818
+
819
  # Ajustar modelo y optimizar
820
  fit_button.click(
821
  fit_and_optimize_model,
 
834
  download_excel_button # Ruta del Excel de tablas
835
  ]
836
  )
837
+
838
  # Generar y mostrar los gráficos
839
  plot_button.click(
840
  lambda fixed_var, fixed_lvl: (
 
846
  inputs=[fixed_variable_input, fixed_level_input],
847
  outputs=[rsm_plot_output, plot_info, current_index_state, all_figures_state]
848
  )
849
+
850
  # Navegación de gráficos
851
  left_button.click(
852
  lambda current_index, all_figures: navigate_plot('left', current_index, all_figures),
 
858
  inputs=[current_index_state, all_figures_state],
859
  outputs=[rsm_plot_output, plot_info, current_index_state]
860
  )
861
+
862
  # Descargar gráfico actual
863
  download_plot_button.click(
864
  download_current_plot,
865
  inputs=[all_figures_state, current_index_state],
866
  outputs=download_plot_button
867
  )
868
+
869
  # Descargar todos los gráficos en ZIP
870
  download_all_plots_button.click(
871
  download_all_plots_zip,
872
  inputs=[],
873
  outputs=download_all_plots_button
874
  )
875
+
876
  # Descargar todas las tablas en Excel y Word
877
  download_excel_button.click(
878
  fn=lambda: download_all_tables_excel(),
879
  inputs=[],
880
  outputs=download_excel_button
881
  )
882
+
883
  download_word_button.click(
884
  fn=lambda: exportar_word(rsm, rsm.get_all_tables()),
885
  inputs=[],
886
  outputs=download_word_button
887
  )
888
+
889
  # Ejemplo de uso
890
+ gr.Markdown("## Instrucciones:") # Shortened Instructions
891
  gr.Markdown("""
892
+ 1. Click 'Cargar Datos' para usar los datos precargados.
893
+ 2. Click 'Ajustar Modelo y Optimizar'.
894
+ 3. Select 'Variable Fija' and 'Nivel de Variable Fija'.
895
+ 4. Click 'Generar Gráficos'.
896
+ 5. Navigate plots with '<' and '>'.
897
+ 6. Download plots and tables as needed.
 
 
 
898
  """)
899
 
900
  return demo
 
906
  interface.launch(share=True)
907
 
908
  if __name__ == "__main__":
909
+ main()