Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,6 +9,7 @@ from scipy.stats import t, f
|
|
9 |
import gradio as gr
|
10 |
import io
|
11 |
import zipfile
|
|
|
12 |
from datetime import datetime
|
13 |
|
14 |
class RSM_BoxBehnken:
|
@@ -31,7 +32,7 @@ class RSM_BoxBehnken:
|
|
31 |
self.model_simplified = None
|
32 |
self.optimized_results = None
|
33 |
self.optimal_levels = None
|
34 |
-
self.all_figures = [] # Lista para almacenar las
|
35 |
self.x1_name = x1_name
|
36 |
self.x2_name = x2_name
|
37 |
self.x3_name = x3_name
|
@@ -164,14 +165,11 @@ class RSM_BoxBehnken:
|
|
164 |
# Calcular los valores predichos
|
165 |
z_pred = self.model_simplified.predict(prediction_data).values.reshape(x_grid_coded.shape)
|
166 |
|
167 |
-
#
|
168 |
-
varying_variables = [var for var in [self.x1_name, self.x2_name, self.x3_name] if var != fixed_variable]
|
169 |
-
|
170 |
-
# 2. Filtrar por el nivel de la variable fija (en codificado)
|
171 |
fixed_level_coded = self.natural_to_coded(fixed_level, fixed_variable)
|
172 |
subset_data = self.data[np.isclose(self.data[fixed_variable], fixed_level_coded)]
|
173 |
|
174 |
-
#
|
175 |
valid_levels = [-1, 0, 1]
|
176 |
experiments_data = subset_data[
|
177 |
subset_data[varying_variables[0]].isin(valid_levels) &
|
@@ -212,19 +210,16 @@ class RSM_BoxBehnken:
|
|
212 |
# --- Fin de la adición de la cuadrícula ---
|
213 |
|
214 |
# Añadir los puntos de los experimentos en la superficie de respuesta con diferentes colores y etiquetas
|
215 |
-
# Crear una lista de colores y etiquetas para los puntos
|
216 |
colors = px.colors.qualitative.Safe
|
217 |
-
point_labels = []
|
218 |
-
for i, row in experiments_data.iterrows():
|
219 |
-
point_labels.append(f"{row[self.y_name]:.3f}") # Redondear a 3 decimales
|
220 |
|
221 |
fig.add_trace(go.Scatter3d(
|
222 |
x=experiments_x_natural,
|
223 |
y=experiments_y_natural,
|
224 |
z=experiments_data[self.y_name].round(3),
|
225 |
mode='markers+text',
|
226 |
-
marker=dict(size=4, color=colors[:len(experiments_x_natural)]),
|
227 |
-
text=point_labels,
|
228 |
textposition='top center',
|
229 |
name='Experimentos'
|
230 |
))
|
@@ -232,17 +227,36 @@ class RSM_BoxBehnken:
|
|
232 |
# Añadir etiquetas y título con variables naturales
|
233 |
fig.update_layout(
|
234 |
scene=dict(
|
235 |
-
xaxis_title=f"{varying_variables[0]} (
|
236 |
-
yaxis_title=f"{varying_variables[1]} (
|
237 |
zaxis_title=self.y_name,
|
238 |
),
|
239 |
-
title=f"{self.y_name} vs {varying_variables[0]} y {varying_variables[1]}<br><sup>{fixed_variable} fijo en {fixed_level:.3f} (
|
240 |
height=800,
|
241 |
width=1000,
|
242 |
showlegend=True
|
243 |
)
|
244 |
return fig
|
245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
def generate_all_plots(self):
|
247 |
"""
|
248 |
Genera todas las gráficas de RSM, variando la variable fija y sus niveles usando el modelo simplificado.
|
@@ -567,13 +581,12 @@ def load_data(x1_name, x2_name, x3_name, y_name, x1_levels_str, x2_levels_str, x
|
|
567 |
return data.round(3), x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels, gr.update(visible=True)
|
568 |
|
569 |
except Exception as e:
|
570 |
-
#
|
571 |
-
# Aquí, simplemente retornamos nada y ocultamos la sección de análisis
|
572 |
return None, "", "", "", "", [], [], [], gr.update(visible=False)
|
573 |
|
574 |
def fit_and_optimize_model():
|
575 |
if 'rsm' not in globals():
|
576 |
-
return [None]*10
|
577 |
|
578 |
# Ajustar modelos y optimizar
|
579 |
model_completo, pareto_completo = rsm.fit_model()
|
@@ -601,8 +614,7 @@ def fit_and_optimize_model():
|
|
601 |
prediction_table,
|
602 |
contribution_table,
|
603 |
anova_table,
|
604 |
-
rsm.all_figures
|
605 |
-
0 # Inicializar el índice actual
|
606 |
)
|
607 |
|
608 |
def show_plot(all_figures, current_index):
|
@@ -648,13 +660,19 @@ def download_current_plot(all_figures, current_index):
|
|
648 |
current_index (int): Índice de la figura actual.
|
649 |
|
650 |
Returns:
|
651 |
-
|
652 |
"""
|
653 |
if not all_figures:
|
654 |
-
return
|
655 |
fig = all_figures[current_index]
|
656 |
img_bytes = rsm.save_fig_to_bytes(fig)
|
657 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
658 |
|
659 |
def download_all_plots_zip(all_figures):
|
660 |
"""
|
@@ -664,32 +682,47 @@ def download_all_plots_zip(all_figures):
|
|
664 |
all_figures (list): Lista de figuras.
|
665 |
|
666 |
Returns:
|
667 |
-
|
668 |
"""
|
669 |
zip_bytes = rsm.save_figures_to_zip()
|
670 |
if zip_bytes:
|
671 |
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
672 |
-
|
673 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
674 |
|
675 |
def download_all_tables_excel():
|
676 |
"""
|
677 |
Descarga todas las tablas en un archivo Excel con múltiples hojas.
|
678 |
|
679 |
Returns:
|
680 |
-
|
681 |
"""
|
682 |
if 'rsm' not in globals():
|
683 |
-
return
|
684 |
-
|
685 |
tables = rsm.get_all_tables()
|
686 |
excel_buffer = io.BytesIO()
|
687 |
with pd.ExcelWriter(excel_buffer, engine='xlsxwriter') as writer:
|
688 |
for sheet_name, table in tables.items():
|
689 |
table.to_excel(writer, sheet_name=sheet_name, index=False)
|
690 |
excel_buffer.seek(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
691 |
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
692 |
-
|
|
|
|
|
693 |
|
694 |
# --- Crear la interfaz de Gradio ---
|
695 |
|
@@ -727,7 +760,7 @@ with gr.Blocks() as demo:
|
|
727 |
gr.Markdown("## Datos Cargados")
|
728 |
data_output = gr.Dataframe(label="Tabla de Datos", interactive=False)
|
729 |
|
730 |
-
#
|
731 |
with gr.Row(visible=False) as analysis_row:
|
732 |
with gr.Column():
|
733 |
fit_button = gr.Button("Ajustar Modelo y Optimizar")
|
|
|
9 |
import gradio as gr
|
10 |
import io
|
11 |
import zipfile
|
12 |
+
import tempfile
|
13 |
from datetime import datetime
|
14 |
|
15 |
class RSM_BoxBehnken:
|
|
|
32 |
self.model_simplified = None
|
33 |
self.optimized_results = None
|
34 |
self.optimal_levels = None
|
35 |
+
self.all_figures = [] # Lista para almacenar las figuras
|
36 |
self.x1_name = x1_name
|
37 |
self.x2_name = x2_name
|
38 |
self.x3_name = x3_name
|
|
|
165 |
# Calcular los valores predichos
|
166 |
z_pred = self.model_simplified.predict(prediction_data).values.reshape(x_grid_coded.shape)
|
167 |
|
168 |
+
# Filtrar por el nivel de la variable fija (en codificado)
|
|
|
|
|
|
|
169 |
fixed_level_coded = self.natural_to_coded(fixed_level, fixed_variable)
|
170 |
subset_data = self.data[np.isclose(self.data[fixed_variable], fixed_level_coded)]
|
171 |
|
172 |
+
# Filtrar por niveles válidos en las variables que varían
|
173 |
valid_levels = [-1, 0, 1]
|
174 |
experiments_data = subset_data[
|
175 |
subset_data[varying_variables[0]].isin(valid_levels) &
|
|
|
210 |
# --- Fin de la adición de la cuadrícula ---
|
211 |
|
212 |
# Añadir los puntos de los experimentos en la superficie de respuesta con diferentes colores y etiquetas
|
|
|
213 |
colors = px.colors.qualitative.Safe
|
214 |
+
point_labels = [f"{row[self.y_name]:.3f}" for _, row in experiments_data.iterrows()]
|
|
|
|
|
215 |
|
216 |
fig.add_trace(go.Scatter3d(
|
217 |
x=experiments_x_natural,
|
218 |
y=experiments_y_natural,
|
219 |
z=experiments_data[self.y_name].round(3),
|
220 |
mode='markers+text',
|
221 |
+
marker=dict(size=4, color=colors[:len(experiments_x_natural)]),
|
222 |
+
text=point_labels,
|
223 |
textposition='top center',
|
224 |
name='Experimentos'
|
225 |
))
|
|
|
227 |
# Añadir etiquetas y título con variables naturales
|
228 |
fig.update_layout(
|
229 |
scene=dict(
|
230 |
+
xaxis_title=f"{varying_variables[0]} ({self.get_units(varying_variables[0])})",
|
231 |
+
yaxis_title=f"{varying_variables[1]} ({self.get_units(varying_variables[1])})",
|
232 |
zaxis_title=self.y_name,
|
233 |
),
|
234 |
+
title=f"{self.y_name} vs {varying_variables[0]} y {varying_variables[1]}<br><sup>{fixed_variable} fijo en {fixed_level:.3f} ({self.get_units(fixed_variable)}) (Modelo Simplificado)</sup>",
|
235 |
height=800,
|
236 |
width=1000,
|
237 |
showlegend=True
|
238 |
)
|
239 |
return fig
|
240 |
|
241 |
+
def get_units(self, variable_name):
|
242 |
+
"""
|
243 |
+
Define las unidades de las variables para etiquetas.
|
244 |
+
Puedes personalizar este método según tus necesidades.
|
245 |
+
|
246 |
+
Args:
|
247 |
+
variable_name (str): Nombre de la variable.
|
248 |
+
|
249 |
+
Returns:
|
250 |
+
str: Unidades de la variable.
|
251 |
+
"""
|
252 |
+
units = {
|
253 |
+
'Glucosa': 'g/L',
|
254 |
+
'Extracto_de_Levadura': 'g/L',
|
255 |
+
'Triptofano': 'g/L',
|
256 |
+
'AIA_ppm': 'ppm'
|
257 |
+
}
|
258 |
+
return units.get(variable_name, '')
|
259 |
+
|
260 |
def generate_all_plots(self):
|
261 |
"""
|
262 |
Genera todas las gráficas de RSM, variando la variable fija y sus niveles usando el modelo simplificado.
|
|
|
581 |
return data.round(3), x1_name, x2_name, x3_name, y_name, x1_levels, x2_levels, x3_levels, gr.update(visible=True)
|
582 |
|
583 |
except Exception as e:
|
584 |
+
# Mostrar mensaje de error
|
|
|
585 |
return None, "", "", "", "", [], [], [], gr.update(visible=False)
|
586 |
|
587 |
def fit_and_optimize_model():
|
588 |
if 'rsm' not in globals():
|
589 |
+
return [None]*10
|
590 |
|
591 |
# Ajustar modelos y optimizar
|
592 |
model_completo, pareto_completo = rsm.fit_model()
|
|
|
614 |
prediction_table,
|
615 |
contribution_table,
|
616 |
anova_table,
|
617 |
+
rsm.all_figures # Devuelve todas las figuras generadas
|
|
|
618 |
)
|
619 |
|
620 |
def show_plot(all_figures, current_index):
|
|
|
660 |
current_index (int): Índice de la figura actual.
|
661 |
|
662 |
Returns:
|
663 |
+
str: Ruta del archivo PNG temporal.
|
664 |
"""
|
665 |
if not all_figures:
|
666 |
+
return "grafico_actual.png" # Ruta predeterminada en caso de error
|
667 |
fig = all_figures[current_index]
|
668 |
img_bytes = rsm.save_fig_to_bytes(fig)
|
669 |
+
|
670 |
+
# Crear un archivo temporal
|
671 |
+
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
|
672 |
+
temp_file.write(img_bytes)
|
673 |
+
temp_file.close()
|
674 |
+
|
675 |
+
return temp_file.name
|
676 |
|
677 |
def download_all_plots_zip(all_figures):
|
678 |
"""
|
|
|
682 |
all_figures (list): Lista de figuras.
|
683 |
|
684 |
Returns:
|
685 |
+
str: Ruta del archivo ZIP temporal.
|
686 |
"""
|
687 |
zip_bytes = rsm.save_figures_to_zip()
|
688 |
if zip_bytes:
|
689 |
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
690 |
+
zip_filename = f"Graficos_RSM_{timestamp}.zip"
|
691 |
+
|
692 |
+
# Crear un archivo temporal para el ZIP
|
693 |
+
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".zip")
|
694 |
+
temp_file.write(zip_bytes)
|
695 |
+
temp_file.close()
|
696 |
+
|
697 |
+
return temp_file.name
|
698 |
+
return "Graficos_RSM.zip" # Ruta predeterminada en caso de error
|
699 |
|
700 |
def download_all_tables_excel():
|
701 |
"""
|
702 |
Descarga todas las tablas en un archivo Excel con múltiples hojas.
|
703 |
|
704 |
Returns:
|
705 |
+
str: Ruta del archivo Excel temporal.
|
706 |
"""
|
707 |
if 'rsm' not in globals():
|
708 |
+
return "Tablas_RSM.xlsx"
|
709 |
+
|
710 |
tables = rsm.get_all_tables()
|
711 |
excel_buffer = io.BytesIO()
|
712 |
with pd.ExcelWriter(excel_buffer, engine='xlsxwriter') as writer:
|
713 |
for sheet_name, table in tables.items():
|
714 |
table.to_excel(writer, sheet_name=sheet_name, index=False)
|
715 |
excel_buffer.seek(0)
|
716 |
+
|
717 |
+
# Crear un archivo temporal para el Excel
|
718 |
+
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx")
|
719 |
+
temp_file.write(excel_buffer.read())
|
720 |
+
temp_file.close()
|
721 |
+
|
722 |
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
723 |
+
excel_filename = f"Tablas_RSM_{timestamp}.xlsx"
|
724 |
+
|
725 |
+
return temp_file.name
|
726 |
|
727 |
# --- Crear la interfaz de Gradio ---
|
728 |
|
|
|
760 |
gr.Markdown("## Datos Cargados")
|
761 |
data_output = gr.Dataframe(label="Tabla de Datos", interactive=False)
|
762 |
|
763 |
+
# Sección de análisis visible solo después de cargar los datos
|
764 |
with gr.Row(visible=False) as analysis_row:
|
765 |
with gr.Column():
|
766 |
fit_button = gr.Button("Ajustar Modelo y Optimizar")
|