using HTML elements in ggplot captions (shiny App)

Thanks in advance for support this question. I am working on a Shiny App with some data about filed complaints with the State Attorney General's Office. I will produce interactive ggplot graphics and other stuff. I want to give style to the caption of my ggplot with HTML elements (I don't know any other way to do it at the complexity level of what I am trying to do with that caption). Because of the nature of my data and because of the amount of csv and Rdata docs that I use, I can not offer a reproducible example, my apologies for that.

The code below represents the ggplot part and how I introduce it in the renderPlot enviroment. If anyone can tell me how to work with HTML elements inside ggplot's caption or has any other option to introduce space between sentences and bold text(not all the text, just a few words), I will be grateful.

library(extrafont)
loadfonts(device = "win")
library(openxlsx)
library(zoo)
library(ggplot2)
library(gridExtra)
library(shiny)
library(shinyWidgets)
library(shinydashboard)
library(shinyjqui)
library(shinyjs)
library(plyr)
library(dplyr)
library(dbplyr)
library(dint)
library(bbplot)
library(osmdata)
library(stats)

  graph_1 <- reactiveValues()
  observeEvent({
    input$tentativa
    input$provincia
    input$periodo_tipo
    input$periodo_ranking
    input$periodo_ranking_t
    input$periodo_ranking_m
  },{
  

      datos<-datos_f()
      datos<-datos %>% count(datos$delitos)
      datos<-datos %>% 
        rename(
          delitos = `datos$delitos`,
        )
      datos<-join(x = datos, y =catalogo_delito,
                  by = "delitos"  )
      datos$Tipo_Delito_PJ<- NULL
      #eliminar duplicados
      datos<-datos[!duplicated(datos$delitos), ]
      
      datos<-datos[order(datos$n, na.last = TRUE, decreasing = TRUE),]
      datos$n_total<-sum(datos$n)
      datos$porcent<-(datos$n / datos$n_total)*100
      datos$cumfreq<-cumsum(datos$porcent)
      datos<-filter(datos, cumfreq<81)
      datos<-datos[order(datos$porcent, na.last = TRUE, decreasing = TRUE),]
      datos$porcent<-format(round(datos$porcent, 2), nsmall = 2)
      datos$porcent<-as.numeric(datos$porcent)
      datos$cumfreq<-NULL
      datos$n_total<-NULL
      
      NROF =nrow(datos)
      if(NROF !=0)
      {
        
        if (req(input$periodo_tipo)== "Anual") {
          titulo <- paste0("Delitos que representan el 80%  de las denuncias a nivel ", input$provincia, " en ",input$periodo_ranking, " (Valores en porcentajes)")
          # paste0("       Delitos que representan el 80%  de las denuncias\n",
          #        "                             a nivel ", input$provincia, " en ",input$periodo_ranking, " (Valores en porcentajes)")
        }else if (req(input$periodo_tipo)== "Trimestral"){
          titulo <- paste0("Delitos que representan el 80%  de las denuncias a nivel ", input$provincia, " en ",input$periodo_ranking_t, " (Valores en porcentajes)")
          # paste0("       Delitos que representan el 80%  de las denuncias\n",
          #        "                             a nivel ", input$provincia, " en ",input$periodo_ranking_t, " (Valores en porcentajes)")
        }else if (req(input$periodo_tipo)== "Mensual"){
          titulo <- paste0("Delitos que representan el 80%  de las denuncias a nivel ", input$provincia, " en ",input$periodo_ranking_m, " (Valores en porcentajes)")
          # paste0("       Delitos que representan el 80%  de las denuncias\n",
          #      "                             a nivel ", input$provincia, " en ",input$periodo_ranking_m, " (Valores en porcentajes)")

a<-1.02*as.numeric(max(datos$porcent))      
bars <- ggplot(datos, aes(x = reorder(Abreviaciones,-porcent), y = porcent,
                                  sprintf("%0.2f", round(porcent, digits = 2)))) +
          geom_bar(stat="identity", 
                   position="identity", 
                   fill="#1380A1", cex=0.5) +
          bbc_style()+
          theme(plot.title = element_text(size = 20, hjust = 0.5)) +
          ggtitle(wrapper(titulo, 70, 0.0)) +
          geom_text(aes(label=porcent), vjust=-0.18, color="black", size=4.5, fontface = "italic")+
          theme(axis.text.x =element_text(angle=45, hjust=1, vjust=1.15, 
                                                    size=14),
                axis.text.y=element_text(size=13.5),
                plot.caption = element_text(hjust = 1, margin = margin(-10,0,0,-20), size = 12))+
          ylim(0,a)

bars <- bars + labs(caption = htmlhtmltools::tags$caption(paste0(strong("Fuente:")," Sistema de actuaciones fiscales (SIAF)",br(),strong("Elaboración:")," Dirección de Estadística y Sistemas de Información)",br(),strong("Nota:"),br(),p(" Los datos del año 2014 representan a las denuncias registradas a partir del Código Orgánico Integral Penal (Agosto-2014).","Los datos del año ",wrapper(vfecha_anio[length(vfecha_anio)],6,2.0)," representan a las denuncias registradas hasta ",wrapper(tolower(as.character(abrev_mes$nombre[abrev_mes$mes_completo == unique(as.character(substring(reportesFGE2$mes[as.numeric(reportesFGE2$id_mes)==max(as.numeric(reportesFGE2$id_mes))],6,8)))])),6,2.0),"."))) 

#The labs code is what I want to use. I want to introduce html elements to the text of the caption option.
#A possible answer could be using bold text with bold() (I use strong() because it is the bold 
#version of HTML elements), but I don't want the whole expression to be a single sentence. 
#I want to give some space between certain sentences (br() introduce space between to sentences)
#Or maybe introducing another element instead of caption, like annotate, but it is imperative not to
#be obligated to put x and y coordinates because it distorts the image.



        graph_1$plot1<-bars
        
      } else {
        plot(0,0,type="n", xlab = "", ylab = "")
        text(0,0,"", font=2, cex=1.5)
      }
    
    })
  
  # Gráficos 1era pestaña, renderPlot#### 
  output$plot1<-renderPlot({
    
    ##
    withProgress(message = 'Calculation in progress',
                 detail = 'This may take a while...', value = 0, {
                   for (i in 1:15) {
                     incProgress(1/15)
                     Sys.sleep(0.05)
                   }
                 })
    ##
    
    graph_1$plot1
    
  })

This was answered over on Stack Overflow with a nice example of how to use package ggtext. Linking to that question/answer here for completeness. :slightly_smiling_face:

3 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.