VicGerardoPR commited on
Commit
d2640bd
·
verified ·
1 Parent(s): 48a9b19

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -64
app.py CHANGED
@@ -31,33 +31,50 @@ def load_data():
31
  else:
32
  data = pd.read_excel(uploaded_file)
33
 
34
- # Procesar la columna de fecha si existe
35
  if 'HML_TXDATE' in data.columns:
36
  try:
37
- # Convertir a datetime
38
- data['HML_TXDATE'] = pd.to_datetime(data['HML_TXDATE'])
 
39
 
40
- # Extraer el día de la semana
41
- data['DIA_SEMANA'] = data['HML_TXDATE'].dt.day_name()
 
 
 
 
 
 
 
 
42
 
43
- # Crear una columna con el formato español (opcional)
44
- dias_esp = {
45
- 'Monday': 'Lunes',
46
- 'Tuesday': 'Martes',
47
- 'Wednesday': 'Miércoles',
48
- 'Thursday': 'Jueves',
49
- 'Friday': 'Viernes',
50
- 'Saturday': 'Sábado',
51
- 'Sunday': 'Domingo'
52
- }
53
- data['DIA_SEMANA_ESP'] = data['DIA_SEMANA'].map(dias_esp)
54
-
55
- # Extraer otras componentes de tiempo útiles
56
- data['HORA'] = data['HML_TXDATE'].dt.hour
57
- data['MES'] = data['HML_TXDATE'].dt.month
58
- data['AÑO'] = data['HML_TXDATE'].dt.year
59
-
60
- st.success("✅ Columna de fecha 'HML_TXDATE' procesada correctamente")
 
 
 
 
 
 
 
 
61
  except Exception as e:
62
  st.warning(f"No se pudo procesar la columna de fecha: {e}")
63
 
@@ -67,7 +84,70 @@ def load_data():
67
  return None
68
  return None
69
 
70
- # Función para generar gráficos basados en conteos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  def create_count_plot(data, x_col, plot_type):
72
  fig, ax = plt.subplots(figsize=(12, 6))
73
 
@@ -175,49 +255,106 @@ def main():
175
  col_type_df = pd.DataFrame(list(col_types.items()), columns=['Columna', 'Tipo'])
176
  st.dataframe(col_type_df)
177
 
178
- # Selección de columnas y tipo de gráfico
179
- st.subheader("Crear visualización")
180
-
181
- col1, col2 = st.columns(2)
182
-
183
- with col1:
184
- # Visualizaciones basadas en conteo
185
- plot_type = st.selectbox(
186
- "Tipo de gráfico",
187
- ["Barras", "Pastel", "Histograma"]
188
- )
189
 
190
- with col2:
191
- # Mostrar opciones especiales para día de la semana si existe
192
- if 'DIA_SEMANA_ESP' in data.columns:
193
- use_day_of_week = st.checkbox("¿Analizar por día de la semana?")
194
- if use_day_of_week:
195
- x_col = "DIA_SEMANA_ESP"
196
- else:
197
- x_col = st.selectbox("Selecciona la columna para analizar", all_cols)
198
- else:
199
- x_col = st.selectbox("Selecciona la columna para analizar", all_cols)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
- # Crear gráfico
202
- if st.button("Generar visualización"):
203
- try:
204
- st.subheader("Visualización")
205
- fig = create_count_plot(data, x_col, plot_type)
206
- st.pyplot(fig)
207
-
208
- # Botón para descargar la imagen
209
- st.markdown(
210
- get_image_download_link(
211
- fig,
212
- f"{plot_type}_{x_col}",
213
- "📥 Descargar imagen"
214
- ),
215
- unsafe_allow_html=True
216
  )
217
-
218
- except Exception as e:
219
- st.error(f"Error al generar el gráfico: {e}")
220
- st.info("Sugerencia: Verifica que la columna seleccionada sea compatible con el tipo de gráfico.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
  # Ejecutar la aplicación
223
  if __name__ == "__main__":
 
31
  else:
32
  data = pd.read_excel(uploaded_file)
33
 
34
+ # Procesar la columna de fecha si existe (asumiendo que es categórica)
35
  if 'HML_TXDATE' in data.columns:
36
  try:
37
+ # Intentar convertir de formato categórico a datetime
38
+ # Primero, vamos a ver si podemos extraer el día de la semana del formato existente
39
+ data['FECHA_DATETIME'] = pd.to_datetime(data['HML_TXDATE'], errors='coerce')
40
 
41
+ if data['FECHA_DATETIME'].isna().all():
42
+ st.warning("No se pudo convertir automáticamente la columna de fecha. Intenta especificar el formato.")
43
+ fecha_formato = st.text_input(
44
+ "Ingresa el formato de fecha (Ej: %Y/%m/%d %H:%M:%S para aaaa/mm/dd HH:MM:SS)",
45
+ value="%Y/%m/%d %H:%M:%S"
46
+ )
47
+ try:
48
+ data['FECHA_DATETIME'] = pd.to_datetime(data['HML_TXDATE'], format=fecha_formato, errors='coerce')
49
+ except Exception as e:
50
+ st.error(f"Error al convertir fechas con formato personalizado: {e}")
51
 
52
+ if not data['FECHA_DATETIME'].isna().all():
53
+ # Extraer el día de la semana
54
+ data['DIA_SEMANA'] = data['FECHA_DATETIME'].dt.day_name()
55
+
56
+ # Crear una columna con el formato español
57
+ dias_esp = {
58
+ 'Monday': 'Lunes',
59
+ 'Tuesday': 'Martes',
60
+ 'Wednesday': 'Miércoles',
61
+ 'Thursday': 'Jueves',
62
+ 'Friday': 'Viernes',
63
+ 'Saturday': 'Sábado',
64
+ 'Sunday': 'Domingo'
65
+ }
66
+ data['DIA_SEMANA_ESP'] = data['DIA_SEMANA'].map(dias_esp)
67
+
68
+ # Extraer componentes de fecha para agrupación
69
+ data['FECHA_SOLO'] = data['FECHA_DATETIME'].dt.date
70
+ data['SEMANA'] = data['FECHA_DATETIME'].dt.isocalendar().week
71
+ data['MES'] = data['FECHA_DATETIME'].dt.month
72
+ data['AÑO'] = data['FECHA_DATETIME'].dt.year
73
+
74
+ st.success("✅ Columna de fecha 'HML_TXDATE' procesada correctamente")
75
+ else:
76
+ st.warning("No se pudo extraer información de la fecha. Verificar formato.")
77
+
78
  except Exception as e:
79
  st.warning(f"No se pudo procesar la columna de fecha: {e}")
80
 
 
84
  return None
85
  return None
86
 
87
+ # Función para generar gráficos basados en conteos por persona y día/semana
88
+ def create_person_performance_plot(data, person_col, time_unit, metric_col=None, plot_type="Barras"):
89
+ if person_col not in data.columns:
90
+ st.error(f"La columna de persona '{person_col}' no existe en el dataset")
91
+ return None
92
+
93
+ fig, ax = plt.subplots(figsize=(12, 6))
94
+
95
+ # Determinar la columna de tiempo según la unidad seleccionada
96
+ if time_unit == "Día":
97
+ if 'FECHA_SOLO' not in data.columns:
98
+ st.error("La columna de fecha diaria no está disponible. Asegúrate de que la fecha fue procesada correctamente.")
99
+ return None
100
+ time_col = 'FECHA_SOLO'
101
+ time_label = 'Fecha'
102
+ elif time_unit == "Día de semana":
103
+ if 'DIA_SEMANA_ESP' not in data.columns:
104
+ st.error("La columna de día de semana no está disponible. Asegúrate de que la fecha fue procesada correctamente.")
105
+ return None
106
+ time_col = 'DIA_SEMANA_ESP'
107
+ time_label = 'Día de semana'
108
+ elif time_unit == "Semana":
109
+ if 'SEMANA' not in data.columns:
110
+ st.error("La columna de semana no está disponible. Asegúrate de que la fecha fue procesada correctamente.")
111
+ return None
112
+ time_col = 'SEMANA'
113
+ time_label = 'Semana'
114
+ else:
115
+ st.error(f"Unidad de tiempo '{time_unit}' no reconocida")
116
+ return None
117
+
118
+ # Contar unidades o usar la métrica especificada
119
+ if metric_col is None or metric_col == 'Conteo':
120
+ # Agrupar y contar filas
121
+ performance_data = data.groupby([time_col, person_col]).size().reset_index(name='Unidades')
122
+ else:
123
+ # Agrupar y sumar la métrica especificada
124
+ performance_data = data.groupby([time_col, person_col])[metric_col].sum().reset_index(name='Unidades')
125
+
126
+ # Asegurarse de que el dataframe tiene las columnas necesarias
127
+ if set([time_col, person_col, 'Unidades']).issubset(performance_data.columns):
128
+ # Crear visualización según el tipo de gráfico
129
+ if plot_type == "Barras":
130
+ sns.barplot(x=time_col, y='Unidades', hue=person_col, data=performance_data, ax=ax)
131
+ plt.title(f"Unidades por {time_label} y Persona")
132
+ plt.xlabel(time_label)
133
+ plt.ylabel('Unidades')
134
+ plt.xticks(rotation=45, ha='right')
135
+ plt.legend(title="Persona")
136
+ elif plot_type == "Líneas":
137
+ sns.lineplot(x=time_col, y='Unidades', hue=person_col, data=performance_data, marker='o', ax=ax)
138
+ plt.title(f"Tendencia de Unidades por {time_label} y Persona")
139
+ plt.xlabel(time_label)
140
+ plt.ylabel('Unidades')
141
+ plt.xticks(rotation=45, ha='right')
142
+ plt.legend(title="Persona")
143
+ else:
144
+ plt.text(0.5, 0.5, "No se pudieron generar los datos para la visualización",
145
+ ha='center', va='center', transform=ax.transAxes)
146
+
147
+ plt.tight_layout()
148
+ return fig
149
+
150
+ # Función para generar gráficos básicos basados en conteos
151
  def create_count_plot(data, x_col, plot_type):
152
  fig, ax = plt.subplots(figsize=(12, 6))
153
 
 
255
  col_type_df = pd.DataFrame(list(col_types.items()), columns=['Columna', 'Tipo'])
256
  st.dataframe(col_type_df)
257
 
258
+ # Pestaña para diferentes tipos de visualización
259
+ tab1, tab2 = st.tabs(["Visualización por Persona/Tiempo", "Visualización Simple"])
 
 
 
 
 
 
 
 
 
260
 
261
+ # Pestaña 1: Visualización por Persona y Tiempo
262
+ with tab1:
263
+ st.subheader("Rendimiento por Persona y Tiempo")
264
+
265
+ col1, col2, col3, col4 = st.columns(4)
266
+
267
+ with col1:
268
+ # Seleccionar columna de persona
269
+ person_col = st.selectbox(
270
+ "Selecciona la columna de Persona",
271
+ [col for col in all_cols if col_types.get(col) == "Texto/Categórico"]
272
+ )
273
+
274
+ with col2:
275
+ # Seleccionar unidad de tiempo
276
+ time_unit = st.selectbox(
277
+ "Selecciona la unidad de tiempo",
278
+ ["Día", "Día de semana", "Semana"]
279
+ )
280
+
281
+ with col3:
282
+ # Seleccionar tipo de gráfico
283
+ plot_type = st.selectbox(
284
+ "Tipo de gráfico para rendimiento",
285
+ ["Barras", "Líneas"]
286
+ )
287
+
288
+ with col4:
289
+ # Seleccionar columna métrica (opcional)
290
+ metric_options = ["Conteo"] + [col for col in all_cols if col_types.get(col) == "Numérico"]
291
+ metric_col = st.selectbox("Métrica a medir", metric_options)
292
+ if metric_col == "Conteo":
293
+ metric_col = None
294
+
295
+ # Botón para generar visualización de rendimiento
296
+ if st.button("Generar Visualización de Rendimiento"):
297
+ try:
298
+ fig = create_person_performance_plot(
299
+ data,
300
+ person_col,
301
+ time_unit,
302
+ metric_col,
303
+ plot_type
304
+ )
305
+ if fig:
306
+ st.pyplot(fig)
307
+
308
+ # Botón para descargar la imagen
309
+ st.markdown(
310
+ get_image_download_link(
311
+ fig,
312
+ f"Rendimiento_{person_col}_{time_unit}",
313
+ "📥 Descargar imagen"
314
+ ),
315
+ unsafe_allow_html=True
316
+ )
317
+ except Exception as e:
318
+ st.error(f"Error al generar el gráfico: {e}")
319
+ st.info("Sugerencia: Verifica que las columnas seleccionadas existan y sean compatibles.")
320
 
321
+ # Pestaña 2: Visualización Simple
322
+ with tab2:
323
+ st.subheader("Visualización de Conteos Simples")
324
+
325
+ col1, col2 = st.columns(2)
326
+
327
+ with col1:
328
+ # Visualizaciones basadas en conteo
329
+ plot_type = st.selectbox(
330
+ "Tipo de gráfico simple",
331
+ ["Barras", "Pastel", "Histograma"]
 
 
 
 
332
  )
333
+
334
+ with col2:
335
+ # Seleccionar columna para analizar
336
+ x_col = st.selectbox("Selecciona la columna para analizar", all_cols)
337
+
338
+ # Crear gráfico simple
339
+ if st.button("Generar Visualización Simple"):
340
+ try:
341
+ st.subheader("Visualización")
342
+ fig = create_count_plot(data, x_col, plot_type)
343
+ st.pyplot(fig)
344
+
345
+ # Botón para descargar la imagen
346
+ st.markdown(
347
+ get_image_download_link(
348
+ fig,
349
+ f"{plot_type}_{x_col}",
350
+ "📥 Descargar imagen"
351
+ ),
352
+ unsafe_allow_html=True
353
+ )
354
+
355
+ except Exception as e:
356
+ st.error(f"Error al generar el gráfico: {e}")
357
+ st.info("Sugerencia: Verifica que la columna seleccionada sea compatible con el tipo de gráfico.")
358
 
359
  # Ejecutar la aplicación
360
  if __name__ == "__main__":