Search code examples
rmachine-learningpngvisualization

Hide elements of htmlwidget plot before saving as PNG


I've been using a library in R called 'aweSOM.' It's a library based upon providing HTML-interactive visuals for self-organising maps (SOMs).

aweSOM produces some nicer visuals than similar SOM packages, so I'd to use it. However, the problem is two-fold:

  1. HTML-interactive visuals are not suitable for publication.
  2. When I save as a PNG, there is (interactive) text remaining on the PNG 'Hover Over The Plot For Information.'

Therefore, I wondered if it is possible to write a function such that the 'plot' is saved as a PNG but without the interactive text above?

Therefore, effectively write a function that saves only a square of a particular size that would omit the text?

Would appreciate your feedback and assistance.

install.packages("aweSOM")
library(aweSOM)

full.data <- iris
train.data <- full.data[, c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")]
train.data <- scale(train.data)

set.seed(1465)
init <- somInit(train.data, 4, 4)
iris.som <- kohonen::som(train.data, grid = kohonen::somgrid(4, 4, "hexagonal"), 
                         rlen = 100, alpha = c(0.05, 0.01), radius = c(2.65,-2.65), 
                         dist.fcts = "sumofsquares", init = init)

superclust_pam <- cluster::pam(iris.som$codes[[1]], 3)
superclasses_pam <- superclust_pam$clustering

###########
#PROBLEMATIC PLOT WITH INTERACTIVE TEXT
##########

plot <- aweSOMplot(som = iris.som, type = "Cloud", data = full.data, 
           variables = c("Species", "Sepal.Length", "Sepal.Width",  
                         "Petal.Length", "Petal.Width"), 
           superclass = superclasses_pam)

All help would be appreciated with fixing the visualisation. A vignette is here:

https://cran.r-project.org/web/packages/aweSOM/vignettes/aweSOM.html#the-awesom-package

enter image description here


Solution

  • How these labels are created

    If you have a look at the aweSOMplot() R source, you'll see it prepends two <h4> html tags to the actual plot (called res):

    res <- htmlwidgets::prependContent(res, htmltools::tag("h4", list(id= paste0(res$elementId, "-info"))))
    res <- htmlwidgets::prependContent(res, htmltools::tag("h4", list(id= paste0(res$elementId, "-message"))))
    

    The aweSOMwidget.js source then adds the relevant text:

    document.getElementById(infoId).innerHTML = "Hover over the plot for information.";
    document.getElementById(messageId).innerHTML = "-";
    

    How to hide the labels

    Create an R function to set an htmlwidgets::htmlwidget element to be invisible:

    hide_element  <- function(el) {
      el$attribs$style  <- 'visibility: hidden;'
      el
    }
    

    Then apply this to the prepended objects in your plot:

    plot$prepend  <- lapply(plot$prepend, hide_element)
    

    This now produces a plot as desired:

    enter image description here

    Note: if you want to remove the - below the plot as well, simply apply the function to the appended elements too:

    to_hide  <- c("prepend", "append")
    plot[to_hide]  <- lapply(plot[to_hide], \(l) lapply(l, hide_element))
    # ^^ plot is now as above but without the "-" below it