From Data to Narrative

Interactive Storytelling with Shiny

Francisco Alfaro

2025-04-09

Agenda

  • No

  • Nope

  • Jamás

Tachado

Regla de Storytelling #1

Nunca reveles el final antes de tiempo.
Siempre eleva la tensión y el dramatismo

Agenda (v2)

  1. Nunca reveles el final
  2. Los detalles son importantes, pero no todos los detalles son importantes.
  3. Tu primera versión será horrible.
  4. Muestra, no cuentes.

Data Storytelling

¿Por qué Data Storytelling?

¿Qué es el Storytelling?

🔥 Las historias son la primera tecnología humana

Esos cerebros tan hackables…


Regla del máximo y final (Peak-End Rule)


Rating de Game of Thrones, por Kelvin Neo

Narrativa



Usar trucos de Storytelling (narrativa) para crear presentaciones que serán recordadas y que causarán impacto

🎭 Las emociones generan acciones

El mejor ejemplo



¿Podemos hacer que millones de personas compartan estadísticas en redes sociales?

Regla de Storytelling #2

Los detalles son importantes, pero no todos los detalles son importantes.

Ejemplos

🔢 No compartas números

🪶Comparte una historia



(C) Storytelling with Data, por Cole Nussbaumer Knaflic.

Regla de Storytelling #3

Tu primera versión siempre será horrible.

Ejemplos

🥱 1° versión \(<\)\(<\) 😊 última versión

Usar chatbots de IA para:


  • Plantillas personalizadas a medida
  • Automatizar estructura del contenido
  • Ahorro de tiempo en diseño
  • Adaptación al estilo y preferencias

💡 Chatbots A.I. - Ideas

Usar chatbots de IA para:


  • Analogías y ejemplos
  • Mejores traducciones
  • Prompts para crear imágenes
  • No busques imágenes, créalas!

💡 Chatbots A.I. - Imágenes

Regla de Storytelling #4

Explicar menos y mostrar más

Explicar menos y mostrar más


import matplotlib.pyplot as plt

# Data
categories = ['Yes', 'No']
values = [75, 25]

# Create the bar chart
plt.figure(figsize=(10, 4))
plt.bar(categories, values, color=['lightblue', 'salmon'])
plt.title('😊 Do you like the presentation so far? 😊')

# Display the plot
plt.show()


Quarto


Quarto es un sistema abierto para publicaciones científicas con markdown y código interactivo (Python/R).

Código: example.qmd

---
title: "Habits"
author: "John Doe"
format:
  revealjs:
    transition: fade
    theme: black
    toc: true
    center: true
---

## Getting up

- Turn off alarm
- Get out of bed

---

## Going to sleep 
::: { .incremental }

- Get in bed
- Count sheep

:::

Slides: example.html

Ejemplos

import matplotlib.pyplot as plt

# Data
categories = ['Yes', 'No']
values = [75, 25]

# Create the bar chart
plt.figure(figsize=(10, 4))
plt.bar(categories, values, color=['lightblue', 'salmon'])
plt.title('😊 Do you like the presentation so far? 😊')

# Display the plot
plt.show()

Quarto Extensiones


Las extensiones son una herramienta poderosa para modificar y ampliar el comportamiento de Quarto.

Tachado

🌐 Quarto WebR y Quarto Pyodide


  1. WebR: Ejecuta código R en el navegador, sin instalaciones.

    # Para instalar WebR en tu entorno
    remotes::install_github("attiyap/WebR")
  2. Pyodide : Idem pero para Python.

    # Para instalar Pyodide
    pip install pyodide

Tachado

Ejemplos

Shiny



Shiny es un paquete de R que permite crear aplicaciones web interactivas fácilmente usando R (También disponible para python).

Shiny

🌐 Quarto Shinylive


Código para desplegar aplicaciones Shiny que se ejecutarán completamente en el navegador, utilizando Pyodide y webR (Python y R compilados a WebAssembly).

R: Ejemplos de Shinylive en R
Python: Ejemplos de Shinylive en Python

Quarto & Shiny

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 550

from shiny import App, ui, render, reactive
import matplotlib.pyplot as plt
import io
import base64

# Function to generate the plot dynamically based on input values
def create_plot(yes_value, no_value):
    categories = ['Yes', 'No']
    values = [yes_value, no_value]

    fig, ax = plt.subplots(figsize=(10, 3))
    ax.bar(categories, values, color=['lightblue', 'salmon'])
    ax.set_title('😊 Do you like the presentation so far? 😊')

    # Convert the image to base64 for display in Shiny
    buf = io.BytesIO()
    plt.savefig(buf, format="png")
    plt.close(fig)
    buf.seek(0)
    encoded_image = base64.b64encode(buf.getvalue()).decode()
    return f'<img src="data:image/png;base64,{encoded_image}" style="max-width:100%;">'

# UI definition
app_ui = ui.page_fluid(
    ui.h2("Interactive Survey"),
    
    # Sliders to change values dynamically
    ui.input_slider("yes_value", "Yes responses:", min=0, max=50, value=20),
    ui.input_slider("no_value", "No responses:", min=0, max=50, value=10),
    
    # Output area for the plot
    ui.output_ui("plot_output")
)

# Server function
def server(input, output, session):
    @output
    @render.ui
    def plot_output():
        return ui.HTML(create_plot(input.yes_value(), input.no_value()))

# Create the Shiny app
app = App(app_ui, server)

Agenda (v2)

  1. Nunca reveles el final
  2. Los detalles son importantes, pero no todos los detalles son importantes
  3. Tu primera versión será horrible
  4. Muestra, no cuentes

🎉 ¡Gracias por Participar!


❓¿Preguntas?

👏 Responder encuesta

🥳 Gracias de Nuevo

🔗 Nuestro Sitio Web: seth-nut.github.io/resources.