Home > database >  Other plots disappear when DataExplorer::plot_str() called
Other plots disappear when DataExplorer::plot_str() called

Time:10-01

I have been using R and RStudio with base and ggplot for a couple of years. Lately, it seems that when some plots are generated, other plots are lost/deleted.

In RStudio, I use the "Plots" pane/tab, and the blue left and right arrows to view the plots that have been created. By disappears, I mean a plot was created and visible here, but if I use the arrows, I can't see it anymore. It was there, and it is not there anymore, it has "disappeared".

enter image description here

After running the code below using "Source" button, which does 3 plots, I can only see 2 plots. If I step through the code using Command-Return, I see the 3 plots generated, but then the middle one gets lost.

After doing more testing, I see for this code it is the call to:

DataExplorer::plot_str(mtcars)

that is the problem. If I comment that line and use another plot from DataExplorer like:

DataExplorer::plot_intro(mtcars)

all the plots are available after the script is complete.

I believe everything is using the latest versions:

  1. mac os - 11.5.2
  2. R - R version 4.1.1 (2021-08-10)
  3. RStudio - RStudio 2021.09.0 351
  4. R libraries - have just updated all the r libraries

Here is a simple base case that seems to recreate the issue. In the example below I am using the DataExplorer library, but I get similar stuff happening in Keras.

Code

###########################   Start Initialisation   ########################################################################################

# Remove objects from environment
rm(list = ls())

# Clear the R studio console
cat("\014")

# Clear all plots in R studio
try(dev.off(dev.list()["RStudioGD"]),silent<-TRUE)
try(dev.off(),silent<-TRUE)

# Load packages, installing first if not already installed
if (!require(DataExplorer)) {
  install.packages("DataExplorer")
  library(DataExplorer)
}

##################################

# Use base plotting to plot iris, this works
base::plot(iris, main="iris 1")

# Use DataExplorer::plot_str() to plot mtcars, this works, but then disappears 
data("mtcars")
# DataExplorer::plot_str(mtcars) # This causes the problem
DataExplorer::plot_intro(mtcars) # This works

# This plot appears, but seems to cause the one above "mtcars" to disappear
base::plot(iris, main="iris 2")

sessionInfo()

Output:


> # Clear all plots in R studio
> try(dev.off(dev.list()["RStudioGD"]),silent<-TRUE)
null device 
          1 

> try(dev.off(),silent<-TRUE)

> # Load packages, installing first if not already installed
> if (!require(DataExplorer)) {
    install.packages("DataExplorer")
    library(DataExpl .... [TRUNCATED] 

> ##################################
> 
> # Use base plotting to plot iris, this works
> base::plot(iris, main="iris 1")

> # Use DataExplorer::plot_str() to plot mtcars, this works, but then disappears 
> data("mtcars")

> DataExplorer::plot_str(mtcars)

> # This plot appears but seems to cause the one above "mtcars" to disappear
> base::plot(iris, main="iris 2")

> sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 11.5.2

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib

locale:
[1] en_AU.UTF-8/en_AU.UTF-8/en_AU.UTF-8/C/en_AU.UTF-8/en_AU.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] DataExplorer_0.8.2

loaded via a namespace (and not attached):
 [1] pillar_1.6.3      compiler_4.1.1    tools_4.1.1       digest_0.6.28     jsonlite_1.7.2    evaluate_0.14     lifecycle_1.0.1   tibble_3.1.4      gtable_0.3.0      pkgconfig_2.0.3  
[11] rlang_0.4.11      igraph_1.2.6      DBI_1.1.1         yaml_2.2.1        parallel_4.1.1    xfun_0.26         fastmap_1.1.0     gridExtra_2.3     dplyr_1.0.7       knitr_1.36       
[21] generics_0.1.0    vctrs_0.3.8       htmlwidgets_1.5.4 grid_4.1.1        tidyselect_1.1.1  glue_1.4.2        data.table_1.14.2 R6_2.5.1          fansi_0.5.0       rmarkdown_2.11   
[31] ggplot2_3.3.5     purrr_0.3.4       magrittr_2.0.1    scales_1.1.1      ellipsis_0.3.2    htmltools_0.5.2   networkD3_0.4     assertthat_0.2.1  colorspace_2.0-2  utf8_1.2.2       
[41] munsell_0.5.0     crayon_1.4.1   

I thought perhaps the issue was due to mixing different plotting libraries, but the code below which draws 6 plots, 3 using base:plot() and 3 using ggplot2::ggplot() works and generates 6 plots that I can navigate through in RStudio using the blue left and right arrow buttons on the "Plots" pane/tab.

base::plot(mpg, main="mpg 1 - base")
ggplot2::ggplot(mpg, aes(displ, hwy, colour = class))   
  geom_point()   
  ggtitle("mpg 1 - ggplot2")

base::plot(ToothGrowth, main="ToothGrowth 2 - base")
ggplot2::ggplot(ToothGrowth, aes(x=supp, y=len, fill=dose)) 
  geom_boxplot()  
  ggtitle("ToothGrowth 2 - ggplot2")

base::plot(iris, main="iris 3 - base")
ggplot2::ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, fill=Species)) 
  geom_boxplot()  
  ggtitle("iris 3 - ggplot2")

RStudio is:

RStudio 2021.09.0 351 "Ghost Orchid" Release (077589bcad3467ae79f318afe8641a1899a51606, 2021-09-20) for macOS
Mozilla/5.0 (Macintosh; Intel Mac OS X 11_5_2) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.12.10 Chrome/69.0.3497.128 Safari/537.36

Mac os version:

(base)  % uname -a
Darwin xxxx.lan 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 x86_64

(base)  % sw_vers
ProductName:    macOS
ProductVersion: 11.5.2
BuildVersion:   20G95

CodePudding user response:

I think the reason is a simple one: you're not outputting a real plot (static).

DataExplorer::plot_intro(mtcars) is the problematic "plot" and the underlying code for this includes diagonalNetwork towards the end of the function:

DataExplorer
function (data, type = c("diagonal", "radial"), max_level = NULL, 
    print_network = TRUE, ...) 
{
    i <- idx <- parent <- NULL
    str_output_raw <- capture.output(str(data, vec.len = 0, give.attr = FALSE, 
        give.length = FALSE, list.len = 2000000000L))
    str_output <- unlist(lapply(str_output_raw, function(x) {
        gsub(" \\.{2}\\@", "\\$\\@", x)
    }))
    n <- length(str_output)
    base_split <- tstrsplit(str_output[2:n], "\\$")
    nest_level <- (nchar(base_split[[1]]) - nchar(gsub(" \\.{2}", 
        "", base_split[[1]])))/3   1
    diff_nl <- diff(nest_level)
    s4_start_index <- which(diff_nl > 1L)   1L
    if (length(s4_start_index) > 0) {
        s4_end_index <- which(diff_nl == -2L)
        s4_index_range <- unique(unlist(lapply(s4_start_index, 
            function(i) {
                seq.int(i, s4_end_index[which.min(abs(s4_end_index - 
                  i))])
            })))
        nest_level[s4_index_range] <- nest_level[s4_index_range] - 
            1L
    }
    if (is.null(max_level)) {
        max_level <- max(nest_level)
    }
    else if (max_level <= 0 | max_level > max(nest_level)) {
        stop(paste0("max_level should be between 1 and ", 
            max(nest_level)))
    }
    else {
        max_level <- max_level
    }
    comp_split <- tstrsplit(base_split[[2]], ":")
    comp_root <- gsub(" ", "", comp_split[[1]])
    comp_root[which(comp_root == "")] <- make.names(comp_root[which(comp_root == 
        "")], unique = TRUE)
    if (anyDuplicated(comp_root)) 
        comp_root[which(duplicated(comp_root))] <- make.names(comp_root[which(duplicated(comp_root))], 
            unique = TRUE)
    comp_output <- paste0(comp_root, " (", trimws(gsub("NULL|\\.{3}|\\.{2}", 
        "", comp_split[[2]])), ")")
    str_dt <- data.table(idx = seq_along(nest_level), nest_level, 
        parent = comp_output)[nest_level <= max_level]
    str_dt <- str_dt[str_dt[, list(i = idx, nest_level = nest_level - 
        1, child = parent)], on = list(nest_level, idx < i), 
        mult = "last"]
    drop_columns(str_dt[is.na(parent), `:=`(parent, paste0("root (", 
        str_output[1], ")"))], c("idx", "nest_level"))
    str_to_list <- function(str_dt, root_name = as.character(str_dt[["parent"]][1])) {
        str_list <- list(name = root_name)
        children <- str_dt[parent == root_name][["child"]]
        if (length(children) > 0) {
            str_list[["children"]] <- lapply(children, 
                str_to_list, str_dt = str_dt)
        }
        str_list
    }
    str_list <- str_to_list(str_dt)
    if (print_network) {
        type <- match.arg(type)
        if (type == "diagonal") 
            print(diagonalNetwork(str_list, ...))
        if (type == "radial") 
            print(radialNetwork(str_list, ...))
    }
    invisible(str_list)
}

where diagonalNetwork uses htmlwidgets:

function (List, height = NULL, width = NULL, fontSize = 10, fontFamily = "serif", 
    linkColour = "#ccc", nodeColour = "#fff", nodeStroke = "steelblue", 
    textColour = "#111", opacity = 0.9, margin = NULL) 
{
    if (!is.list(List)) 
        stop("List must be a list object.")
    root <- List
    margin <- margin_handler(margin)
    options = list(height = height, width = width, fontSize = fontSize, 
        fontFamily = fontFamily, linkColour = linkColour, nodeColour = nodeColour, 
        nodeStroke = nodeStroke, textColour = textColour, margin = margin, 
        opacity = opacity)
    htmlwidgets::createWidget(name = "diagonalNetwork", 
        x = list(root = root, options = options), width = width, 
        height = height, htmlwidgets::sizingPolicy(padding = 10, 
            browser.fill = TRUE), package = "networkD3")
}

htmlwidgets is an interactive "plot" and opens under RStudio's viewer pane and not the static plots pane.

  • Related