C2MV commited on
Commit
aca9c5b
verified
1 Parent(s): 0fc9d0e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +236 -130
app.py CHANGED
@@ -95,7 +95,7 @@ def generar_graficos(df_valid, n_replicas, unidad_medida, palette_puntos, estilo
95
  sns.set(style="whitegrid")
96
  plt.rcParams.update({'figure.autolayout': True})
97
 
98
- fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
99
 
100
  # Obtener colores de las paletas
101
  colors_puntos = sns.color_palette(palette_puntos, as_cmap=False)
@@ -267,6 +267,36 @@ Fecha: {datetime.now().strftime('%d/%m/%Y %H:%M')}
267
  """
268
  return informe, evaluacion['estado']
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  def actualizar_analisis(df, n_replicas, unidad_medida):
271
  if df is None or df.empty:
272
  return "Error en los datos", None, "No se pueden generar an谩lisis", df
@@ -312,7 +342,7 @@ def actualizar_graficos(df, n_replicas, unidad_medida,
312
  if df is None or df.empty:
313
  return None
314
 
315
- # Asegurarse de que los c谩lculos est茅n actualizados
316
  df = calcular_promedio_desviacion(df, n_replicas, unidad_medida)
317
 
318
  col_predicha_num = "Concentraci贸n Predicha Num茅rica"
@@ -339,6 +369,55 @@ def actualizar_graficos(df, n_replicas, unidad_medida,
339
 
340
  return fig
341
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  def exportar_informe_word(df_valid, informe_md, unidad_medida):
343
  # Crear documento Word
344
  doc = docx.Document()
@@ -593,9 +672,20 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
593
 
594
  with gr.Tab("馃搳 An谩lisis y Reporte"):
595
  estado_output = gr.Textbox(label="Estado", interactive=False)
596
- graficos_output = gr.Plot(label="Gr谩ficos de An谩lisis")
597
-
598
- # Opciones y botones debajo del gr谩fico
 
 
 
 
 
 
 
 
 
 
 
599
  with gr.Row():
600
  # Paletas de colores disponibles en Seaborn
601
  paletas_colores = ["deep", "muted", "pastel", "bright", "dark", "colorblind", "Set1", "Set2", "Set3"]
@@ -640,7 +730,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
640
  mostrar_linea_ajuste = gr.Checkbox(value=True, label="Mostrar L铆nea de Ajuste")
641
  mostrar_linea_ideal = gr.Checkbox(value=True, label="Mostrar L铆nea Ideal")
642
  mostrar_puntos = gr.Checkbox(value=True, label="Mostrar Puntos")
643
- graficar_btn = gr.Button("馃搳 Graficar", variant="primary")
644
 
645
  with gr.Row():
646
  copiar_btn = gr.Button("馃搵 Copiar Informe", variant="secondary")
@@ -654,148 +743,165 @@ with gr.Blocks(theme=gr.themes.Soft()) as interfaz:
654
  # Informe al final
655
  informe_output = gr.Markdown(elem_id="informe_output")
656
 
657
- # Eventos
658
- input_components = [tabla_output]
659
- output_components = [estado_output, graficos_output, informe_output, tabla_output]
660
 
661
- # Evento al presionar el bot贸n Calcular
662
- calcular_btn.click(
663
- fn=actualizar_analisis,
664
- inputs=[tabla_output, replicas_slider, unidad_input],
665
- outputs=output_components
666
- )
667
 
668
- # Evento para graficar con opciones seleccionadas
669
- graficar_btn.click(
670
- fn=actualizar_graficos,
671
- inputs=[
672
- tabla_output, replicas_slider, unidad_input,
673
- palette_puntos_dropdown, estilo_puntos_dropdown,
674
- palette_linea_ajuste_dropdown, estilo_linea_ajuste_dropdown,
675
- palette_linea_ideal_dropdown, estilo_linea_ideal_dropdown,
676
- palette_barras_error_dropdown,
677
- mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos
678
- ],
679
- outputs=graficos_output
680
- )
681
 
682
- # Evento para limpiar datos
683
- limpiar_btn.click(
684
- fn=limpiar_datos,
685
- inputs=[replicas_slider],
686
- outputs=[concentracion_input, unidad_input, filas_slider, tabla_output, estado_output, graficos_output, informe_output]
687
- )
 
 
 
 
 
 
 
 
688
 
689
- # Eventos de los botones de ejemplo
690
- ejemplo_ufc_btn.click(
691
- fn=cargar_ejemplo_ufc,
692
- inputs=[replicas_slider],
693
- outputs=[concentracion_input, unidad_input, filas_slider, tabla_output]
694
- )
695
 
696
- ejemplo_od_btn.click(
697
- fn=cargar_ejemplo_od,
698
- inputs=[replicas_slider],
699
- outputs=[concentracion_input, unidad_input, filas_slider, tabla_output]
700
- )
 
701
 
702
- # Evento para generar datos sint茅ticos
703
- sinteticos_btn.click(
704
- fn=generar_datos_sinteticos_evento,
705
- inputs=[tabla_output, replicas_slider, unidad_input],
706
- outputs=tabla_output
707
- )
708
 
709
- # Evento al presionar el bot贸n Ajustar Decimales
710
- ajustar_decimales_btn.click(
711
- fn=ajustar_decimales_evento,
712
- inputs=[tabla_output, decimales_slider],
713
- outputs=tabla_output
714
- )
715
 
716
- # Actualizar tabla al cambiar los par谩metros (sin borrar "Concentraci贸n Real")
717
- def actualizar_tabla_wrapper(df, filas, conc, unidad, replicas):
718
- return actualizar_tabla_evento(df, filas, conc, unidad, replicas)
 
 
 
719
 
720
- concentracion_input.change(
721
- fn=actualizar_tabla_wrapper,
722
- inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
723
- outputs=tabla_output
724
- )
725
 
726
- unidad_input.change(
727
- fn=actualizar_tabla_wrapper,
728
- inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
729
- outputs=tabla_output
730
- )
731
 
732
- filas_slider.change(
733
- fn=actualizar_tabla_wrapper,
734
- inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
735
- outputs=tabla_output
736
- )
737
 
738
- replicas_slider.change(
739
- fn=actualizar_tabla_wrapper,
740
- inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
741
- outputs=tabla_output
742
- )
743
 
744
- # No agregamos un evento para decimales_slider.change, para evitar borrar la columna "Concentraci贸n Real"
745
-
746
- # Evento de copiar informe utilizando JavaScript
747
- copiar_btn.click(
748
- None,
749
- [],
750
- [],
751
- js="""
752
- function() {
753
- const informeElement = document.querySelector('#informe_output');
754
- const range = document.createRange();
755
- range.selectNode(informeElement);
756
- window.getSelection().removeAllRanges();
757
- window.getSelection().addRange(range);
758
- document.execCommand('copy');
759
- window.getSelection().removeAllRanges();
760
- alert('Informe copiado al portapapeles');
761
- }
762
- """
763
- )
764
 
765
- # Eventos de exportar informes
766
- exportar_word_btn.click(
767
- fn=exportar_word,
768
- inputs=[tabla_output, informe_output, unidad_input],
769
- outputs=exportar_word_file
770
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
771
 
772
- exportar_latex_btn.click(
773
- fn=exportar_latex,
774
- inputs=[tabla_output, informe_output],
775
- outputs=exportar_latex_file
776
- )
 
777
 
778
- # Inicializar la interfaz con el ejemplo base
779
- def iniciar_con_ejemplo():
780
- n_replicas = 1
781
- df = generar_tabla(7, 2000000, "UFC", n_replicas)
782
- # Valores reales de ejemplo
783
- df[f"Concentraci贸n Real 1 (UFC)"] = [2000000, 1600000, 1200000, 800000, 400000, 200000, 100000]
784
- estado, fig, informe, df = actualizar_analisis(df, n_replicas, "UFC")
785
- return (
786
- 2000000,
787
- "UFC",
788
- 7,
789
- df,
790
- estado,
791
- fig,
792
- informe
793
  )
794
 
795
- interfaz.load(
796
- fn=iniciar_con_ejemplo,
797
- outputs=[concentracion_input, unidad_input, filas_slider, tabla_output, estado_output, graficos_output, informe_output]
798
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
799
 
800
  # Lanzar la interfaz
801
  if __name__ == "__main__":
 
95
  sns.set(style="whitegrid")
96
  plt.rcParams.update({'figure.autolayout': True})
97
 
98
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5)) # Tama帽o ajustado a (10, 5)
99
 
100
  # Obtener colores de las paletas
101
  colors_puntos = sns.color_palette(palette_puntos, as_cmap=False)
 
267
  """
268
  return informe, evaluacion['estado']
269
 
270
+ def generar_graficos_actualizados(df_valid, n_replicas, unidad_medida,
271
+ palette_puntos, estilo_puntos,
272
+ palette_linea_ajuste, estilo_linea_ajuste,
273
+ palette_linea_ideal, estilo_linea_ideal,
274
+ palette_barras_error,
275
+ mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos):
276
+ # Funci贸n separada para evitar redundancia
277
+ return generar_graficos(df_valid, n_replicas, unidad_medida,
278
+ palette_puntos, estilo_puntos,
279
+ palette_linea_ajuste, estilo_linea_ajuste,
280
+ palette_linea_ideal, estilo_linea_ideal,
281
+ palette_barras_error,
282
+ mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos)
283
+
284
+ def evaluar_puntos_seleccionados(df, puntos_seleccionados):
285
+ if not puntos_seleccionados:
286
+ return df # Si no se selecciona ning煤n punto, retornar el DataFrame completo
287
+
288
+ # Filtrar el DataFrame para incluir solo los puntos seleccionados
289
+ df_filtrado = df.iloc[puntos_seleccionados].reset_index(drop=True)
290
+ return df_filtrado
291
+
292
+ def generar_lista_puntos(df):
293
+ """Genera una lista de descripciones de puntos para el CheckboxGroup"""
294
+ lista = []
295
+ for idx, row in df.iterrows():
296
+ descripcion = f"Punto {idx + 1}: Predicha={row['Concentraci贸n Predicha (UFC)']}, Real Promedio={row['Concentraci贸n Real Promedio (UFC)']}"
297
+ lista.append(descripcion)
298
+ return lista
299
+
300
  def actualizar_analisis(df, n_replicas, unidad_medida):
301
  if df is None or df.empty:
302
  return "Error en los datos", None, "No se pueden generar an谩lisis", df
 
342
  if df is None or df.empty:
343
  return None
344
 
345
+ # Calcular promedio y desviaci贸n est谩ndar
346
  df = calcular_promedio_desviacion(df, n_replicas, unidad_medida)
347
 
348
  col_predicha_num = "Concentraci贸n Predicha Num茅rica"
 
369
 
370
  return fig
371
 
372
+ def recalcular(df, n_replicas, unidad_medida, puntos_seleccionados,
373
+ palette_puntos, estilo_puntos,
374
+ palette_linea_ajuste, estilo_linea_ajuste,
375
+ palette_linea_ideal, estilo_linea_ideal,
376
+ palette_barras_error,
377
+ mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos):
378
+ if df is None or df.empty:
379
+ return "Error en los datos", None, "No se pueden generar an谩lisis", df, []
380
+
381
+ # Calcular promedio y desviaci贸n est谩ndar
382
+ df = calcular_promedio_desviacion(df, n_replicas, unidad_medida)
383
+
384
+ # Filtrar los puntos seleccionados
385
+ df_filtrado = evaluar_puntos_seleccionados(df, puntos_seleccionados)
386
+
387
+ col_predicha_num = "Concentraci贸n Predicha Num茅rica"
388
+ col_real_promedio = f"Concentraci贸n Real Promedio ({unidad_medida})"
389
+
390
+ # Convertir columnas a num茅rico
391
+ df_filtrado[col_predicha_num] = pd.to_numeric(df_filtrado[col_predicha_num], errors='coerce')
392
+ df_filtrado[col_real_promedio] = pd.to_numeric(df_filtrado[col_real_promedio], errors='coerce')
393
+
394
+ df_valid = df_filtrado.dropna(subset=[col_predicha_num, col_real_promedio])
395
+
396
+ if len(df_valid) < 2:
397
+ return "Se necesitan m谩s datos", None, "Se requieren al menos dos valores reales para el an谩lisis", df, []
398
+
399
+ # Calcular la regresi贸n y agregar 'Ajuste Lineal'
400
+ slope, intercept, r_value, p_value, std_err = stats.linregress(df_valid[col_predicha_num], df_valid[col_real_promedio])
401
+ df_valid['Ajuste Lineal'] = intercept + slope * df_valid[col_predicha_num]
402
+
403
+ # Generar gr谩fico con opciones seleccionadas
404
+ fig = generar_graficos(
405
+ df_valid, n_replicas, unidad_medida,
406
+ palette_puntos, estilo_puntos,
407
+ palette_linea_ajuste, estilo_linea_ajuste,
408
+ palette_linea_ideal, estilo_linea_ideal,
409
+ palette_barras_error,
410
+ mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos
411
+ )
412
+
413
+ # Generar informe
414
+ informe, estado = generar_informe_completo(df_valid, n_replicas, unidad_medida)
415
+
416
+ # Generar lista de puntos para selecci贸n
417
+ lista_puntos = generar_lista_puntos(df)
418
+
419
+ return estado, fig, informe, df, lista_puntos
420
+
421
  def exportar_informe_word(df_valid, informe_md, unidad_medida):
422
  # Crear documento Word
423
  doc = docx.Document()
 
672
 
673
  with gr.Tab("馃搳 An谩lisis y Reporte"):
674
  estado_output = gr.Textbox(label="Estado", interactive=False)
675
+ with gr.Row():
676
+ with gr.Column(scale=3):
677
+ graficos_output = gr.Plot(label="Gr谩ficos de An谩lisis")
678
+ with gr.Row():
679
+ # Opciones y botones debajo del gr谩fico
680
+ graficar_btn = gr.Button("馃搳 Graficar", variant="primary")
681
+ with gr.Column(scale=1):
682
+ puntos_seleccionados = gr.CheckboxGroup(
683
+ choices=[],
684
+ label="Seleccionar Puntos para Ajustar",
685
+ )
686
+ recalcular_btn = gr.Button("馃攣 Recalcular", variant="primary")
687
+
688
+ # Opciones de personalizaci贸n de gr谩ficos
689
  with gr.Row():
690
  # Paletas de colores disponibles en Seaborn
691
  paletas_colores = ["deep", "muted", "pastel", "bright", "dark", "colorblind", "Set1", "Set2", "Set3"]
 
730
  mostrar_linea_ajuste = gr.Checkbox(value=True, label="Mostrar L铆nea de Ajuste")
731
  mostrar_linea_ideal = gr.Checkbox(value=True, label="Mostrar L铆nea Ideal")
732
  mostrar_puntos = gr.Checkbox(value=True, label="Mostrar Puntos")
 
733
 
734
  with gr.Row():
735
  copiar_btn = gr.Button("馃搵 Copiar Informe", variant="secondary")
 
743
  # Informe al final
744
  informe_output = gr.Markdown(elem_id="informe_output")
745
 
746
+ # Eventos
747
+ input_components = [tabla_output]
748
+ output_components = [estado_output, graficos_output, informe_output, tabla_output]
749
 
750
+ # Evento al presionar el bot贸n Calcular
751
+ calcular_btn.click(
752
+ fn=actualizar_analisis,
753
+ inputs=[tabla_output, replicas_slider, unidad_input],
754
+ outputs=[estado_output, graficos_output, informe_output, tabla_output]
755
+ )
756
 
757
+ # Evento para graficar con opciones seleccionadas
758
+ graficar_btn.click(
759
+ fn=actualizar_graficos,
760
+ inputs=[
761
+ tabla_output, replicas_slider, unidad_input,
762
+ palette_puntos_dropdown, estilo_puntos_dropdown,
763
+ palette_linea_ajuste_dropdown, estilo_linea_ajuste_dropdown,
764
+ palette_linea_ideal_dropdown, estilo_linea_ideal_dropdown,
765
+ palette_barras_error_dropdown,
766
+ mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos
767
+ ],
768
+ outputs=graficos_output
769
+ )
770
 
771
+ # Evento para recalcular basado en puntos seleccionados
772
+ recalcular_btn.click(
773
+ fn=recalcular,
774
+ inputs=[
775
+ tabla_output, replicas_slider, unidad_input,
776
+ puntos_seleccionados,
777
+ palette_puntos_dropdown, estilo_puntos_dropdown,
778
+ palette_linea_ajuste_dropdown, estilo_linea_ajuste_dropdown,
779
+ palette_linea_ideal_dropdown, estilo_linea_ideal_dropdown,
780
+ palette_barras_error_dropdown,
781
+ mostrar_linea_ajuste, mostrar_linea_ideal, mostrar_puntos
782
+ ],
783
+ outputs=[estado_output, graficos_output, informe_output, tabla_output, puntos_seleccionados]
784
+ )
785
 
786
+ # Evento para limpiar datos
787
+ limpiar_btn.click(
788
+ fn=limpiar_datos,
789
+ inputs=[replicas_slider],
790
+ outputs=[concentracion_input, unidad_input, filas_slider, tabla_output, estado_output, graficos_output, informe_output]
791
+ )
792
 
793
+ # Eventos de los botones de ejemplo
794
+ ejemplo_ufc_btn.click(
795
+ fn=cargar_ejemplo_ufc,
796
+ inputs=[replicas_slider],
797
+ outputs=[concentracion_input, unidad_input, filas_slider, tabla_output]
798
+ )
799
 
800
+ ejemplo_od_btn.click(
801
+ fn=cargar_ejemplo_od,
802
+ inputs=[replicas_slider],
803
+ outputs=[concentracion_input, unidad_input, filas_slider, tabla_output]
804
+ )
 
805
 
806
+ # Evento para generar datos sint茅ticos
807
+ sinteticos_btn.click(
808
+ fn=generar_datos_sinteticos_evento,
809
+ inputs=[tabla_output, replicas_slider, unidad_input],
810
+ outputs=tabla_output
811
+ )
812
 
813
+ # Evento al presionar el bot贸n Ajustar Decimales
814
+ ajustar_decimales_btn.click(
815
+ fn=ajustar_decimales_evento,
816
+ inputs=[tabla_output, decimales_slider],
817
+ outputs=tabla_output
818
+ )
819
 
820
+ # Actualizar tabla al cambiar los par谩metros (sin borrar "Concentraci贸n Real")
821
+ def actualizar_tabla_wrapper(df, filas, conc, unidad, replicas):
822
+ return actualizar_tabla_evento(df, filas, conc, unidad, replicas)
 
 
823
 
824
+ concentracion_input.change(
825
+ fn=actualizar_tabla_wrapper,
826
+ inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
827
+ outputs=tabla_output
828
+ )
829
 
830
+ unidad_input.change(
831
+ fn=actualizar_tabla_wrapper,
832
+ inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
833
+ outputs=tabla_output
834
+ )
835
 
836
+ filas_slider.change(
837
+ fn=actualizar_tabla_wrapper,
838
+ inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
839
+ outputs=tabla_output
840
+ )
841
 
842
+ replicas_slider.change(
843
+ fn=actualizar_tabla_wrapper,
844
+ inputs=[tabla_output, filas_slider, concentracion_input, unidad_input, replicas_slider],
845
+ outputs=tabla_output
846
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847
 
848
+ # No agregamos un evento para decimales_slider.change, para evitar borrar la columna "Concentraci贸n Real"
849
+
850
+ # Evento de copiar informe utilizando JavaScript
851
+ copiar_btn.click(
852
+ None,
853
+ [],
854
+ [],
855
+ js="""
856
+ function() {
857
+ const informeElement = document.querySelector('#informe_output');
858
+ const range = document.createRange();
859
+ range.selectNode(informeElement);
860
+ window.getSelection().removeAllRanges();
861
+ window.getSelection().addRange(range);
862
+ document.execCommand('copy');
863
+ window.getSelection().removeAllRanges();
864
+ alert('Informe copiado al portapapeles');
865
+ }
866
+ """
867
+ )
868
 
869
+ # Eventos de exportar informes
870
+ exportar_word_btn.click(
871
+ fn=exportar_word,
872
+ inputs=[tabla_output, informe_output, unidad_input],
873
+ outputs=exportar_word_file
874
+ )
875
 
876
+ exportar_latex_btn.click(
877
+ fn=exportar_latex,
878
+ inputs=[tabla_output, informe_output],
879
+ outputs=exportar_latex_file
 
 
 
 
 
 
 
 
 
 
 
880
  )
881
 
882
+ # Inicializar la interfaz con el ejemplo base
883
+ def iniciar_con_ejemplo():
884
+ n_replicas = 1
885
+ df = generar_tabla(7, 2000000, "UFC", n_replicas)
886
+ # Valores reales de ejemplo
887
+ df[f"Concentraci贸n Real 1 (UFC)"] = [2000000, 1600000, 1200000, 800000, 400000, 200000, 100000]
888
+ estado, fig, informe, df = actualizar_analisis(df, n_replicas, "UFC")
889
+ lista_puntos = generar_lista_puntos(df)
890
+ return (
891
+ 2000000,
892
+ "UFC",
893
+ 7,
894
+ df,
895
+ estado,
896
+ fig,
897
+ informe,
898
+ lista_puntos
899
+ )
900
+
901
+ interfaz.load(
902
+ fn=iniciar_con_ejemplo,
903
+ outputs=[concentracion_input, unidad_input, filas_slider, tabla_output, estado_output, graficos_output, informe_output, puntos_seleccionados]
904
+ )
905
 
906
  # Lanzar la interfaz
907
  if __name__ == "__main__":