OneThingApp / app.py
Migue1804's picture
Update app.py
190984a verified
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import io
# Configuración de la aplicación
st.set_page_config(page_title="Solo una cosa!... ¿Cómo priorizar ante tanto ruido?", layout="wide")
# Display the image above the title
st.image('OneThing.jpg', use_column_width=True)
# Crear pestañas
tabs = st.tabs(["Resumen del Libro", "Aplicación", "Acerca de mí"])
# Función para generar contenido HTML
def export_as_html():
buffer = io.StringIO()
# Crear una pestaña HTML interactiva (por ejemplo, la pestaña de "Aplicación")
with st.container():
st.markdown("<h1>Pestaña de Aplicación Exportada</h1>", unsafe_allow_html=True)
st.write("Aquí se exporta el contenido interactivo de la aplicación.")
# Generar gráficos en HTML
fig = px.scatter(x=[1, 2, 3], y=[1, 3, 2])
fig.write_html(buffer) # Guardar gráfico en HTML en el buffer
return buffer.getvalue()
# Pestaña 1: Resumen del libro
with tabs[0]:
st.header("Resumen del libro: 'Lo Único' de Gary Keller y Jay Papasan")
resumen = """
##
"Lo Único" se centra en la premisa de que el éxito se logra al enfocar nuestros esfuerzos en una sola cosa a la vez. A través de este enfoque, podemos maximizar nuestros resultados y disminuir la sensación de agobio.
### **Conceptos Clave del Libro**
1. **La Falacia de la Igualdad:**
- No todas las cosas son igual de importantes; debemos identificar y priorizar lo que realmente importa.
2. **El Mito de la Multitarea:**
- La multitarea no existe como tal; dividir nuestra atención disminuye la eficiencia.
3. **Disciplina vs. Hábito:**
- El éxito se basa más en la formación de hábitos que en la autodisciplina férrea.
4. **La Importancia de Pensar en Grande:**
- Establecer metas ambiciosas nos impulsa a superarnos.
5. **El Valor del Propósito:**
- Un propósito claro nos ayuda a tomar decisiones rápidas y efectivas.
### **Conclusión**
El enfoque en "Lo Único" ofrece una guía práctica para identificar prioridades y maximizar la efectividad en todas las áreas de la vida.
"""
st.markdown(resumen)
# Pestaña 2: Aplicación
with tabs[1]:
st.header("Identificar Lo Único")
# Descripción de cómo construir lo único
st.markdown("""
### ¿Qué es "Lo Único"?
**"Lo Único"** es la tarea o acción más importante que puedes hacer en un área específica de tu vida o trabajo, de tal manera que, al lograrla, todo lo demás se vuelve más fácil o incluso innecesario. El enfoque es identificar la acción que tiene el mayor impacto y concentrar tus esfuerzos en ella para maximizar los resultados y reducir la dispersión de tareas no esenciales.
Para identificar **"Lo Único"** en un área de tu vida, pregúntate:
> _"¿Qué es lo único que puedo hacer ahora [en relación con un área específica de mi vida o trabajo], gracias a lo cual todo lo demás me resulte más fácil o innecesario?"_
### Pasos para construir "Lo Único":
1. **Evalúa tus metas a largo plazo**: Considera hacia dónde quieres dirigirte, tanto personal como profesionalmente.
2. **Divide tus objetivos en áreas clave**: Por ejemplo, salud, carrera, relaciones, finanzas, etc.
3. **Prioriza en función del impacto**: ¿Qué actividad, si se realiza, tiene el mayor impacto en esa área? Esa será "Lo Único".
4. **Céntrate en un solo paso a la vez**: La clave es elegir una acción concreta que puedas ejecutar, que hará que el resto de las tareas sean más fáciles o innecesarias.
""")
# Separador y llamada de atención para el input
st.markdown("---") # Línea separadora para dar mayor contraste
st.markdown("""
### Ahora es tu turno:
**Escribe a continuación tu propia descripción de _"Lo Único"_ que deseas lograr.**
_(Este será el primer paso clave hacia tu meta más importante)_:
""")
# Campo de texto más grande para definir "Lo Único"
lo_unico = st.text_area("Describe 'Lo Único' que quieres lograr",
value="Desarrollar un sistema de gestión que centralice todas las operaciones y sus resultados para reducir los tiempos de toma de decisiones",
height=150)
# Para resaltar visualmente el campo de entrada
st.markdown("<style>textarea {background-color: #f0f0f5; font-size: 18px;}</style>", unsafe_allow_html=True)
# Añadir un botón que resalte la acción a tomar
if st.button("Confirmar mi 'Lo Único'"):
st.success(f"Has definido tu 'Lo Único' como: {lo_unico}")
# Sidebar para mostrar DataFrames
st.sidebar.header("Paso 1: Ingresa las actividades que realizas actualmente (Califica tus actividades de 0 a 5)")
st.sidebar.markdown("##### *Realiza un listado de las actividades típicas en tu semana y analiza su nivel de importancia y urgencia para lograr lo único!*")
data = {
"Actividad": [
"Desarrollar sistema de gestión centralizado", # Actividad clave para lograr "lo único"
"Definir la estrategia de operaciones", # Fundamental para la centralización de operaciones
"Monitorear resultados y KPI críticos", # Actividad clave para reducir tiempos de decisión
"Automatizar reportes de resultados", # Directamente relacionado con la centralización y reducción de tiempo
"Optimización del flujo de información", # Alineado con la eficiencia operativa
"Capacitar equipo en nuevas herramientas", # Importante para la implementación del sistema
"Revisar el proceso de toma de decisiones", # Relevante para el objetivo, pero no tan urgente
"Planificación estratégica de nuevos proyectos", # Puede apoyar a "lo único" en el futuro
"Optimización del proceso de ventas", # Contribuye indirectamente al propósito general
"Responder emails administrativos", # Consumidor de tiempo, pero delegable
"Reuniones internas no estructuradas", # Requieren atención, pero pueden ser delegadas
"Revisar métricas operativas no críticas", # Poco impacto en "lo único", urgentes pero delegables
"Revisar y archivar documentos antiguos", # Poco impacto, eliminable
"Configurar reuniones recurrentes", # Delegable
"Comprar suministros generales", # No relacionado con "lo único"
"Actualizar la base de datos no prioritaria", # Delegable si no es crítica
"Limpieza y mantenimiento de oficina" # Eliminable
],
"Importancia": [5, 5, 5, 4, 4, 4, 4, 3, 3, 2, 2, 2, 1, 2, 2, 1, 1], # Ajustado con base en "lo único"
"Urgencia": [4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1], # Basado en la urgencia operativa
"Tiempo invertido (horas/semana)": [12, 10, 8, 6, 5, 5, 4, 4, 3, 3, 3, 2, 1, 2, 2, 1, 1] # Horas ajustadas
}
# El total de horas suma aproximadamente 50-55 horas por semana, incluyendo interrupciones.
df = pd.DataFrame(data)
editable_df = st.sidebar.data_editor(df, key="editable_df")
# Sección 1: Actividades actuales y matriz de Eisenhower
st.header("¿En qué inviertes tu tiempo y donde te debes enfocar?")
# Matriz de Eisenhower
st.subheader("Matriz de Eisenhower y Pareto")
# Clasificación en la matriz de Eisenhower
conditions = [
(editable_df['Importancia'] >= 2.5) & (editable_df['Urgencia'] >= 2.5),
(editable_df['Importancia'] >= 2.5) & (editable_df['Urgencia'] < 2.5),
(editable_df['Importancia'] < 2.5) & (editable_df['Urgencia'] >= 2.5),
(editable_df['Importancia'] < 2.5) & (editable_df['Urgencia'] < 2.5),
]
choices = ['Hacer ahora', 'Planificar', 'Delegar', 'Eliminar']
editable_df['Eisenhower'] = np.select(conditions, choices, default='No clasificado')
# Mostrar la Matriz de Eisenhower en un gráfico de burbujas
col1, col2 = st.columns(2)
# Definir los colores para los diferentes criterios de Eisenhower
color_mapping = {
'Hacer ahora': 'red',
'Planificar': 'blue',
'Delegar': 'green',
'Eliminar': 'gray'
}
with col1:
fig_eisenhower = px.scatter(
editable_df,
x='Urgencia',
y='Importancia',
size='Tiempo invertido (horas/semana)', # El tamaño de la burbuja se basa en el tiempo invertido
color='Eisenhower',
color_discrete_map=color_mapping, # Mapa de colores basado en 'Eisenhower'
hover_name='Actividad',
labels={'Importancia': 'Importancia', 'Urgencia': 'Urgencia'},
title="Matriz de Eisenhower (escala 0 a 5)"
)
# Fijar los rangos de los ejes x y y de 0 a 5
fig_eisenhower.update_xaxes(range=[0, 5.5])
fig_eisenhower.update_yaxes(range=[0, 5.5])
# Agregar líneas vertical y horizontal en 2.5
fig_eisenhower.add_shape(type="line", x0=2.5, x1=2.5, y0=0, y1=5,
line=dict(color="Black", width=2, dash="dash"))
fig_eisenhower.add_shape(type="line", x0=0, x1=5, y0=2.5, y1=2.5,
line=dict(color="Black", width=2, dash="dash"))
fig_eisenhower.update_layout(
template="plotly_white")
st.plotly_chart(fig_eisenhower, use_container_width=True)
# Pareto basado en el tiempo invertido
editable_df['Ponderación'] = editable_df['Tiempo invertido (horas/semana)'] # Usar tiempo invertido para el Pareto
pareto_df = editable_df.sort_values(by='Ponderación', ascending=False)
# Gráfico de Pareto
# Calcular frecuencias relativas y acumuladas
pareto_df['Frecuencia Relativa'] = pareto_df['Ponderación'] / pareto_df['Ponderación'].sum()
pareto_df['Frecuencia Acumulada'] = pareto_df['Frecuencia Relativa'].cumsum()
# Asignar colores basados en la columna Eisenhower
pareto_df['Color'] = pareto_df['Eisenhower'].map(color_mapping)
with col2:
fig_pareto = go.Figure()
# Gráfico de barras para frecuencias relativas, coloreando según el criterio de Eisenhower
fig_pareto.add_trace(go.Bar(
x=pareto_df['Actividad'],
y=pareto_df['Frecuencia Relativa'],
name='Frecuencia Relativa',
marker_color=pareto_df['Color'] # Colorear barras según la clasificación Eisenhower
))
# Gráfico de línea para frecuencias acumuladas
fig_pareto.add_trace(go.Scatter(
x=pareto_df['Actividad'],
y=pareto_df['Frecuencia Acumulada'],
name='Frecuencia Acumulada',
marker_color='red',
yaxis='y2',
mode='lines+markers'
))
# Agregar una línea horizontal en el 80%
fig_pareto.add_trace(go.Scatter(
x=[pareto_df['Actividad'].iloc[0], pareto_df['Actividad'].iloc[-1]],
y=[0.8, 0.8],
mode='lines',
name='Límite del 80%',
line=dict(color='orange', width=2, dash='dash')
))
# Ajustar el diseño del gráfico de Pareto para mejor legibilidad
fig_pareto.update_layout(
title='Pareto de Actividades por Tiempo Invertido',
yaxis=dict(title='Frecuencia Relativa', range=[0, 1]), # Eje y de 0 a 1
yaxis2=dict(title='Frecuencia Acumulada', overlaying='y', side='right', range=[0, 1]), # Eje y secundario de 0 a 1
legend=dict(x=0.1, y=0.9),
xaxis=dict(
tickangle=-45, # Rotar las etiquetas del eje x
title_text='Actividades',
tickfont=dict(size=10) # Reducir el tamaño de la fuente para que las etiquetas sean legibles
),
template="plotly_white",
margin=dict(b=150), # Agregar margen inferior para evitar que las etiquetas se corten
width=1000 # Ajustar el ancho del gráfico para mejorar la visualización
)
st.plotly_chart(fig_pareto, use_container_width=True)
# Sección 2: Matriz de habilidades y análisis de brechas
st.header("¿Qué habilidades debes desarrollar para enfocarte en lo único?")
# Sidebar para ajustar el journey de prioridades
st.sidebar.header("Paso 2: Ingresa los datos de tus habilidades para lograr lo Único!")
st.sidebar.markdown("##### *Realiza una autovaloración de las habilidades que consideras que debes desarrollar, el nivel que consideras que tienes actualmente y cual debes alcanzar*")
skills_data = {
'Habilidad': [
'Comunicación', # Importante para transmitir información y colaborar con el equipo.
'Gestión de Proyectos', # Necesaria para planificar, ejecutar y supervisar proyectos eficientemente.
'Análisis de Datos', # Habilidad para interpretar datos y tomar decisiones informadas.
'Programación Básica', # Conocimiento de herramientas tecnológicas para implementar soluciones.
'Liderazgo', # Clave para guiar y motivar a los miembros del equipo.
'Pensamiento Crítico', # Habilidad para resolver problemas y tomar decisiones efectivas.
'Gestión del Cambio', # Capacidad para implementar cambios organizativos sin interrupciones.
'Gestión del Tiempo', # Importante para priorizar tareas y cumplir plazos.
'Conocimientos en Tecnología', # Familiaridad con herramientas y sistemas de gestión que pueden facilitar procesos.
'Capacitación y Desarrollo', # Habilidad para entrenar y desarrollar al equipo en nuevas herramientas o procesos.
'Planificación Estratégica' # Capacidad para alinear las operaciones con los objetivos organizacionales.
],
'Habilidad Actual': [3, 4, 2, 3, 3, 4, 2, 3, 3, 2, 3], # Evaluación de habilidades actuales
'Habilidad Requerida': [5, 5, 4, 4, 4, 5, 4, 5, 4, 3, 4] # Habilidades necesarias para lograr el propósito
}
# Asegúrate de que todas las listas tengan la misma longitud
skills_df = pd.DataFrame(skills_data)
skills_df = st.sidebar.data_editor(skills_df, key="skills_df")
# Crear columnas para el heatmap y el gráfico de radar
col3, col4 = st.columns(2)
# Mostrar matriz de habilidades como heatmap usando Plotly
with col3:
st.markdown("### ¿Dónde estás vs. dónde debes estar?")
# Creación del heatmap con escala de color 'Greens'
heatmap_fig = go.Figure(data=go.Heatmap(
z=skills_df[['Habilidad Actual', 'Habilidad Requerida']].values, # Los valores de habilidad actual y requerida
x=['Habilidad Actual', 'Habilidad Requerida'], # Ejes x
y=skills_df['Habilidad'], # Ejes y
colorscale='Greens', # Escala de colores que va de verde oscuro (bajo) a verde brillante (alto)
colorbar=dict(title='Nivel de Habilidad')
))
heatmap_fig.update_layout(
title='Heatmap de Habilidades',
template="plotly_white",
yaxis=dict(title='Habilidad')
)
st.plotly_chart(heatmap_fig, use_container_width=True)
# Gráfico de radar para el análisis de brechas
with col4:
st.markdown("### ¿Cuál habilidad debes desarrollar más?")
fig_radar = go.Figure()
# Trazos de habilidades requeridas (verde brillante para niveles altos)
fig_radar.add_trace(go.Scatterpolar(
r=skills_df['Habilidad Requerida'],
theta=skills_df['Habilidad'],
fill='toself',
name='Habilidad Requerida',
line=dict(color='rgba(0, 100, 0, 0.7)'), # Verde oscuros
fillcolor='rgba(0, 100, 0, 0.2)' # Verde oscuro para el área
))
# Trazos de habilidades actuales (verde oscuro para niveles bajos)
fig_radar.add_trace(go.Scatterpolar(
r=skills_df['Habilidad Actual'],
theta=skills_df['Habilidad'],
fill='toself',
name='Habilidad Actual',
line=dict(color='rgba(0, 235, 0, 0.7)'), # Verde brillante
fillcolor='rgba(0, 235, 0, 0.7)' # Verde claro para el área
))
fig_radar.update_layout(
polar=dict(
radialaxis=dict(
visible=True,
range=[0, 5] # Rango de habilidades
)),
showlegend=True,
template="plotly_white",
title="Análisis de Brechas en Habilidades"
)
st.plotly_chart(fig_radar, use_container_width=True)
# Sección 3: Journey Map (Funnel o Bowtie)
st.header("Traza tu hoja de ruta: Escribe tus actividades prioritarias y los resultados que esperas!")
# Sidebar para ajustar el journey de prioridades
st.sidebar.header("Paso 3: Ingresa los datos de tu hoja de ruta y resultados esperados, y enfocate en ellos!")
st.sidebar.markdown("##### *En este punto ya sabes en que inviertes el tiempo y que decisiones debes tomar, además sabes las habilidades que debes desarrollar. Ingresa las actividades prioritarias para alcanzar lo único!, ingresa los resultados actuales y esperados al desarrollar lo único y concentrate en ellos!*")
# Datos de actividades prioritarias con KPI medibles y tiempos
journey_data = {
'Prioridad': [
'Definir la estrategia del sistema de gestión',
'Análisis de requerimientos',
'Implementación del sistema de gestión',
'Optimización de procesos existentes',
'Reuniones con clientes clave',
'Capacitación del equipo sobre el nuevo sistema',
'Revisión de KPIs establecidos'
],
'Resultado': [
'Número de no conformidades', # KPI para medir la efectividad de la estrategia
'Número de requerimientos definidos', # KPI para medir el alcance del análisis
'Satisfacción del usuario (%)', # KPI de satisfacción tras la implementación
'Eficiencia del proceso (horas)', # KPI para evaluar la eficiencia del proceso
'Número de decisiones informadas', # KPI para medir la efectividad de las reuniones
'Número de capacitaciones completadas', # KPI para medir el alcance de la capacitación
'Costo de implementación (USD)' # KPI relacionado con el costo
],
'Inicio': [
'2024-10-01',
'2024-10-03',
'2024-10-10',
'2024-10-15',
'2024-10-20',
'2024-10-25',
'2024-10-30'
],
'Fin': [
'2024-10-02',
'2024-10-04',
'2024-10-14',
'2024-10-25',
'2024-10-22',
'2024-10-30',
'2024-11-05'
],
'KPI Actual': [15, 8, 70, 30, 5, 1, 2000], # Valores actuales de KPIs
'KPI Esperado': [5, 10, 90, 10, 20, 3, 800], # Valores esperados de KPIs
'Mejor': ['<', '>', '>', '<', '>', '>', '<'] # Indica si el KPI debe mejorar o disminuir
}
# Crear DataFrame
journey_df = pd.DataFrame(journey_data)
journey_df = st.sidebar.data_editor(journey_df, key="journey_df")
# Calcular el tiempo basado en las fechas (en horas)
journey_df['Inicio'] = pd.to_datetime(journey_df['Inicio'])
journey_df['Fin'] = pd.to_datetime(journey_df['Fin'])
journey_df['Tiempo (horas)'] = (journey_df['Fin'] - journey_df['Inicio']).dt.days * 8 # Suponiendo 8 horas por día
# Calcular el porcentaje de mejora considerando la dirección
def calculate_percentage_improvement(current, expected, direction):
if current == 0 and expected > 0:
return 100 # Mejora completa al ir de 0 a un valor positivo
elif current > 0 and expected == 0:
return -100 # Disminución completa
elif current == 0 and expected == 0:
return 0 # Sin cambio
else:
if direction == '>':
return ((expected - current) / current) * 100 # Mejora esperada
elif direction == '<':
return ((current - expected) / current) * 100 # Disminución esperada
# Aplicar la función para calcular el porcentaje de mejora
journey_df['Porcentaje Mejora'] = journey_df.apply(
lambda row: calculate_percentage_improvement(
row['KPI Actual'],
row['KPI Esperado'],
row['Mejor']
),
axis=1
)
# Normalizar los valores para el funnel
max_tiempo = journey_df['Tiempo (horas)'].max()
max_porcentaje_mejora = journey_df['Porcentaje Mejora'].max()
journey_df['Tiempo Normalizado'] = journey_df['Tiempo (horas)'] / max_tiempo * 100 # Normalización al rango 0-100
journey_df['Porcentaje Mejora Normalizado'] = journey_df['Porcentaje Mejora'] / max_porcentaje_mejora * 100 # Normalización al rango 0-100
# Obtener el número de prioridades para ajustar el eje 'y' dinámicamente
num_prioridades = len(journey_df['Prioridad'])
# Colores para el Funnel
color_actividades = 'rgba(0, 100, 255, 0.8)' # Color azul para actividades priorizadas
color_resultados = 'rgba(255, 165, 0, 0.8)' # Color naranja para resultados esperados
# Gráfico tipo funnel (bowtie) para mostrar el journey map
fig_journey = go.Figure()
# Funnel de actividades priorizadas (vertical)
fig_journey.add_trace(go.Funnel(
y=journey_df['Tiempo Normalizado'],
x=journey_df['Prioridad'], # Mostrar el tiempo normalizado de cada actividad
textinfo="value+label",
name="Actividades Prioritarias",
marker=dict(color=color_actividades), # Aplicar color uniforme para las actividades
orientation="v" # Mantener orientación vertical
))
# Funnel de resultados esperados (vertical)
fig_journey.add_trace(go.Funnel(
y=journey_df['Porcentaje Mejora Normalizado'], # Usar el porcentaje de mejora como resultado
x=journey_df['Resultado'], # Mostrar el KPI como resultado
textinfo="value+label",
name="Resultados Esperados",
marker=dict(color=color_resultados), # Aplicar color uniforme para los resultados
orientation="v" # Mantener orientación vertical
))
# Actualizar la visualización del gráfico
fig_journey.update_layout(
template="plotly_white",
title="Journey Map: Actividades Prioritarias y Resultados Esperados",
funnelmode="stack"
)
st.plotly_chart(fig_journey, use_container_width=True)
# --------------------------- Gantt Chart -----------------------------------
# Crear DataFrame para las actividades priorizadas y fechas
eventos = journey_df[['Prioridad', 'Inicio', 'Fin']].copy()
eventos.columns = ['Evento', 'Fecha de Inicio', 'Fecha de Fin'] # Renombrar columnas
# Crear el gráfico de Gantt con una paleta de colores predefinida
fig_gantt = px.timeline(
eventos,
x_start="Fecha de Inicio",
x_end="Fecha de Fin",
y="Evento",
color='Evento', # Colores automáticos basados en la actividad
title='Gráfico de Gantt de Actividades Prioritarias',
color_discrete_sequence=px.colors.qualitative.Pastel # Usar una paleta clara para asegurar legibilidad
)
# Ajustar las configuraciones del gráfico de Gantt
fig_gantt.update_layout(
template="plotly_white" # Usar un tema claro para evitar colores oscuros en la descarga
)
# Mostrar el gráfico en Streamlit
st.plotly_chart(fig_gantt, use_container_width=True)
# --------------------------- Download Chart -----------------------------------
def export_figures_to_html(figures, title="Exported Figures"):
html = f"<html><head><title>{title}</title></head><body>"
for fig in figures:
html += fig.to_html(full_html=False, include_plotlyjs='cdn')
html += "</body></html>"
return html
# Recopilar todas las figuras que deseas exportar
figuras_a_exportar = [fig_eisenhower, fig_pareto, heatmap_fig, fig_radar,fig_journey, fig_gantt]
# Crear el HTML para descargar
html_export = export_figures_to_html(figuras_a_exportar, title="Exportación de Gráficos de la Aplicación")
st.markdown("### Descarga tus gráficos ")
# Añadir un botón de descarga al final de la pestaña
st.download_button(
label="Descargar Gráficos en HTML",
data=html_export,
file_name="aplicacion_graficos.html",
mime="text/html"
)
# Pestaña 3: Acerca de mí
with tabs[2]:
st.header("Acerca de mí")
acerca_de_mi = """
¡Hola! Soy Migue, desarrollo herramientas para facilitar la visualización y organización de ideas mediante visualizaciones interactivas. Esta aplicación está diseñada para ayudarte a estructurar tus pensamientos de manera eficiente y creativa, utilizando tecnologías de desarrollo de aplicaciones en Python.
**Características de la Aplicación:**
- **Interfaz Intuitiva:** Agrega tus ideas principales y datos en la barra lateral
- **Visualización Interactiva:** Explora tus visualizaciones de manera dinámica y visualmente atractiva.
**Contacto:**
- **Correo Electrónico:** [mail](mailto:josemiguelaguilart.com)
- **LinkedIn:** [LinkedIn](https://www.linkedin.com/in/josemaguilar/)
"""
st.markdown(acerca_de_mi)