El efecto de cada capa en gráficos ggplot

Ggplot se basa en añadir capas a un mismo objeto. En este artículo se utiliza el paquete codehover para visualizar qué efecto tiene cada capa sobre el gráfico final.

Author

Affiliation

Karina Bartolomé

 

Published

July 9, 2021

Citation

Bartolomé, 2021

Visualizaciones con ggplot2 💫

El paquete {ggplot2} 📦 del ecosistema {tidyverse}

1 permite realizar visualizaciones avanzadas en un formato ordenado mediante capas. {codehover} 2 📦 sirve para descomponer un gráfico ggplot en múltiples capas para entender cómo influye cada una sobre la visualización final.

Librerías 📚

Se utilizan las siguientes librerías:

library(tidyverse)
library(rvest)
library(codehover)
library(extrafont)

Audiencia de Mr Robot por episodio 💻

Como ejemplo, utilizo una visualización que realicé para la iniciativa #30DiasDeGraficos:

Diagrama de Florence Nightingale: audiencia de Mr Robot por episodio. Gracias a las coordenadas polares se puede ver el episodio 1 “eps1.0_hellofriend.mov” al lado del final “Hello, Elliot” y me encanta ese contraste#30diasdegraficos, una iniciativa de (R4DS_es?) pic.twitter.com/JkUCVNabcl

— Karina Bartolomé 💚 () June 10, 2020


Se obtienen los datos de Wikipedia con {rvest}

3 📦, un paquete para realizar web scraping siguiendo la lógica del enfoque tidy.

# Wikipedia:
url <- 'https://en.wikipedia.org/wiki/List_of_Mr._Robot_episodes#Ratings'
audiencia <- read_html(url)

# Dataframe a partir de las tablas de audiencia por episodio:
df <- bind_rows(
  audiencia %>% html_nodes("table") %>% .[[8]] %>% 
    html_table(fill = TRUE) %>% mutate(season = 1),
  audiencia %>% html_nodes("table") %>% .[[9]] %>% 
    html_table(fill = TRUE) %>% mutate(season = 2),
  audiencia %>% html_nodes("table") %>% .[[10]] %>% 
    html_table(fill = TRUE) %>% mutate(season = 3),
  audiencia %>% html_nodes("table") %>% .[[11]] %>% 
    html_table(fill = TRUE) %>% mutate(season = 4)
) %>% 
  # Obtener los viewers
  separate(col = `Viewers(millions)`, 
           into = c("viewers", "remove"), sep='\\[') %>% 
  select(-remove) %>% 
  mutate(id = row_number(),
         Title=gsub('"','',Title), 
         viewers = as.numeric(viewers), 
         season = as.factor(season))


# Ángulos de rotación para el gráfico
label_data <- df
number_of_bar <- nrow(label_data)
angle <-  90 - 360 * (df$id-0.5) /number_of_bar 
label_data$hjust<-ifelse( angle < -90, 1, 0)
label_data$angle<-ifelse(angle < -90, angle+180, angle)

df <- df %>% mutate(id=as.factor(id))

👉Se generan las partes del gráfico a mostrar y se almacenan como imágenes.

height = 6
width  = 7
# Primer gráfico:
g <- ggplot(df, aes(x = id, y = viewers)) +
  geom_col(aes(fill = season))

ggplot2::ggsave("./IMG_caso1/1.png", 
                width = width, height = height, dpi = 100)

Sobre el gráfico g original se añaden nuevas capas, guardando cada nueva imagen en la carpeta de imágens:

Show code
# Se suma una capa de coordenadas polares:
g <-  g + coord_polar()+ ylim(0,3)

ggplot2::ggsave("./IMG_caso1/2.png", 
                width = width, height = height, dpi = 100)

# Se suman 2 capas, una del texto de audiencia, otra del nombre de episodio:
g <-  g + geom_text(data=label_data, 
                    aes(x=id, 
                        y=viewers+0.1, 
                        label=paste0(round(viewers,1),"M"), 
                        hjust=hjust), 
            color="red", fontface="bold",alpha=0.6, 
            size=2, angle= label_data$angle)

ggplot2::ggsave("./IMG_caso1/3.png", 
                width = width, height = height, dpi = 100)

g <-  g + geom_text(data=label_data, aes(x=id, 
                                 y=viewers+0.4, 
                                 label=paste(Title), 
                                 hjust=hjust), 
            color="black", fontface="bold",alpha=0.6, size=3, 
            angle= label_data$angle)

ggplot2::ggsave("./IMG_caso1/4.png", 
                width = width, height = height, dpi = 100)

# Se suma una capa de colores:
g <-  g + scale_fill_manual(values = c("#325c38", "#5b8f65",
                                       "#87c595","#b5ffc9"))

ggplot2::ggsave("./IMG_caso1/5.png", 
                width = width, height = height, dpi = 100)

# Se suma una capa de theme_minimal()
g <-  g + theme_minimal()
ggplot2::ggsave("./IMG_caso1/6.png", 
                width = width, height = height, dpi = 100)

# Se suma la capa de theme personalizado:
g <- g + theme(
      axis.text = element_blank(),
      axis.title = element_blank(),
      panel.grid = element_blank(),
      text=element_text(size=20,  family="Andale Mono"),
      legend.direction = 'horizontal',
      legend.position = c(0.5,0.05),
      plot.title=element_text(hjust=0.5)
    )

ggplot2::ggsave("./IMG_caso1/7.png", 
                width = width, height = height, dpi = 100)

# Se añaden labels:
g <- g + labs(fill='Temporada', 
         title='Audiencia de Mr Robot',
         caption='#30diasdegraficos \n Una iniciativa de @R4DS_es')

ggplot2::ggsave("./IMG_caso1/8.png", 
                width = width, height = height, dpi = 100)

📝Se incluye un código css para el formato del output:

Show code
table {
  cursor: pointer; 
  cursor: hand;
  border: none;
  margin-left: auto;
  margin-right: auto;
  width:"80%";
  border:"0"; 
  cellspacing:"0"; 
  cellpadding:"0";
  font-family: "Lucida Console";
}

.hover {background-color: #b5ffc9;}

.image-crop {height: 600px;;}

tab1 { padding-left: 4em; }
tab2 { padding-left: 8em; }

.column {
  float: left;
  width: 50%;
  padding: 10px;
  margin-left: 10px;
  width: 100%;
}

Siguiendo la documentación del paquete {codehover}, también es necesario incluir un .txt de javascript:

Se utilizan las funciones de {codehover} para generar el código html necesario para la visualización final 🌟:

Show code
resultado <- ch_int(type = "incremental", div_tag_add = "class='column'") %>%
  
  ch_row(img = "./IMG_caso1/1.png",
    text = "<div>ggplot(df, aes(x=id, y=viewers))+
      <br> <tab1>geom_col(aes(fill=season))+</br></tab1>
      </div>") %>%
  
  ch_row(img = "./IMG_caso1/2.png",
    text = "<div>coord_polar(start = 0) + ylim(0,3)</div>") %>%
  
  ch_row(img = "./IMG_caso1/3.png", 
    text = '<div>geom_text(data=label_data, aes(x=id, y=viewers+0.1,
       <br><tab1>label=paste0(round(viewers,1),"M"),hjust=hjust),</br></tab1>
       <tab1>color="red", fontface="bold",alpha=0.6, </tab1>
       <tab1>size=2,angle=angle)+</tab1></div>') %>%
  
   ch_row( img = "./IMG_caso1/4.png",
    text ='<div>geom_text(data=label_data, 
      <br><tab1>aes(x=id, y=viewers+0.4, label=Title,hjust=hjust),</br><tab1>
      <tab1> color="black", fontface="bold",alpha=0.6, size=3,</tab1>
      <tab1>angle= label_data$angle)+</tab1></div>') %>%
  
  ch_row(img = "./IMG_caso1/5.png",
    text = '<div>scale_fill_manual(
    <br><tab1>values = c("#325c38", "#5b8f65", "#87c595","#b5ffc9")</br></tab1>
    </div>') %>%
  
  ch_row(img = "./IMG_caso1/6.png",
         text = '<div>theme_minimal()+</div>') %>%
  
  ch_row(img = "./IMG_caso1/7.png", 
    text = '<div>theme(axis.text = element_blank(), 
       <br><tab1>axis.title = element_blank(),</br><tab1>
       <tab1>panel.grid = element_blank(),</tab1>
       <tab1>text=element_text(size=20,family="Andale Mono"),</tab1>
       <tab1>legend.direction = "horizontal", </tab1>
       <tab1>legend.position  = c(0.5,0.05),</tab1>
       <tab1>plot.title=element_text(hjust=0.5))</tab1>
    </div>') %>%
  
    ch_row(img = "./IMG_caso1/8.png",
    text = '<div>labs(fill="Temporada", title="Audiencia de Mr Robot",
      <br><tab1>caption="#30diasdegraficos \n Una iniciativa de R4DS_es")+</br></tab1>
    </div>') %>%
  
  ch_out(img = "./IMG_caso1/1.png", div_tag_add = " class='column'")

⚠️ Al estar realizando un artículo distill, fue necesario visualizar el output generado mediante código inline:

`r resultado`
ggplot(df, aes(x=id, y=viewers))+
geom_col(aes(fill=season))+
coord_polar(start = 0) + ylim(0,3)
geom_text(data=label_data, aes(x=id, y=viewers+0.1,
label=paste0(round(viewers,1),“M”),hjust=hjust), color=“red,”
fontface=“bold,” alpha=0.6, size=2,angle=angle)+
geom_text(data=label_data, aes(x=id, y=viewers+0.4,
label=Title,hjust=hjust), color=“black,”
fontface=“bold,” alpha=0.6, size=3,angle= label_data$angle)+
scale_fill_manual(values = c(“#325c38,” “#5b8f65,” “#87c595,”“#b5ffc9”)
theme_minimal()+
theme(axis.text = element_blank(), axis.title = element_blank(),
panel.grid = element_blank(),
text=element_text(size=20,family=“Andale Mono”), legend.direction = “horizontal,” legend.position= c(0.5,0.05), plot.title=element_text(hjust=0.5))
labs(fill=“Temporada,” title=“Audiencia de Mr Robot,”
caption=“#30diasdegraficos Una iniciativa de R4DS_es”)+

Sin embargo, para html_output se utiliza {htmltools} 📦:

htmltools::HTML(resultado)

Comentarios finales 💬

Visualizar el efecto de cada una de las capas sobre un gráfico permite entender cómo funciona {ggplot2} y puede ser muy útil en ámbitos educativos 📚. Espero poder incorporar otros gráficos a este artículo.

👉 Actualmente {codehover} funciona muy bien para output: html_document. Sin embargo, en distill_article por ahora no encontré forma de generar el output en dos columnas (una código y otra para el gráfico).

Cualquier comentario es bienvenido 🙌 🙌 🙌

Contacto ✉

Karina Bartolome Twitter Badge Linkedin Badge Github Badge Website Badge

Footnotes

  1. Wickham et al. (2019)[↩]
  2. Welle (2021)[↩]
  3. Wickham (2020)[↩]

References

Welle, Arthur. 2021. Codehover: Hoverable HTML Table for Displaying Intermediary Code Results (Pipes). https://github.com/arthurwelle/codehover.
Wickham, Hadley. 2020. Rvest: Easily Harvest (Scrape) Web Pages. https://CRAN.R-project.org/package=rvest.
Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. “Welcome to the tidyverse.” Journal of Open Source Software 4 (43): 1686. https://doi.org/10.21105/joss.01686.

Citation

For attribution, please cite this work as

Bartolomé (2021, July 9). Karina Bartolome: El efecto de cada capa en gráficos ggplot. Retrieved from https://karbartolome-blog.netlify.app/posts/codehover-viz/

BibTeX citation

@misc{bartolomé2021el,
  author = {Bartolomé, Karina},
  title = {Karina Bartolome: El efecto de cada capa en gráficos ggplot},
  url = {https://karbartolome-blog.netlify.app/posts/codehover-viz/},
  year = {2021}
}