HelenaLC / CATALYST

Cytometry dATa anALYsis Tools
67 stars 30 forks source link

plotDiffHeatmap inside an If or TryCatch #267

Closed ramziabb closed 2 years ago

ramziabb commented 2 years ago

So this may be a basic R Studio / compiler issue that clearly I do not have a good understanding of, but hoping there is a simple solution to this.

When I run heatmaps and write them out from CATALYST - the code looks like this:

plotDiffHeatmap(sce, rowData(da_res1$res), all = TRUE, fdr = FDR_cutoff)
funWritePlotPDF("Plot 22.")

Where

funWritePlotPDF <- function(strPlotName) {
  #pdf(file = paste(strPlotDirectory, strPlotName, sep=''))
  pdf(file = paste(strPlotDirectory, strPlotName, sep=''), pointsize = 2)

  dev.set(which = 2)
  dev.copy(which = 4)
  dev.off()  
}

Works great (although I wish the plots were higher resolution I haven't figures out a way to make this happen with a different writing method).

If I run the same code from inside either an If statement of a tryCatch statement, the plot does not write to the R console and therefore does not write out to a file. Can anyone explain why?

tryCatch( { 
    plotDiffHeatmap(sce, rowData(ds_res1$res), all = TRUE, fdr = FDR_cutoff)
    funColorConditions(sce, rowData(ds_res1$res))
    funWritePlotPDF("Plot 24. Compare Each Cluster Itacitinib vs. Control - Intracellular Signaling.PDF")
  }, 
  error = function(e) {
    print("Plot 24 Error")
    print(e)
  })

Or alternatively just show me how to run the following logic:

If there is an error in plotDiffHeatmap, skip the funWritePlotPDF function.

Thanks.

HelenaLC commented 2 years ago

When I try your code, the plot IS written to .pdf inside tryCatch, so I don't see the issue with that. However, yes, it will NOT appear in the console nor be returned as an object. That is because tryCatch essentially "swallows" everything that happens, and only returns the last value (here, this is pdf() printing the graphic's device name). You can think of this the same way as a normal function call: whatever happens, only the last value is returned. Below is an example how to do both: save the plot but also return the object by i) plotting inside tryCatch and ii) saving only when no error occured.

library(CATALYST)
data(PBMC_fs, PBMC_panel, PBMC_md)
sce <- prepData(PBMC_fs, PBMC_panel, PBMC_md)
sce <- cluster(sce, verbose = FALSE)

.plot <- \(sce) plotExprHeatmap(sce, by = "sample_id")

.save <- \(dir, fnm) {
    fnm <- paste0(fnm, ".pdf")
    pdf(file = file.path(dir, fnm), pointsize = 2)
    dev.set(which = 2)
    dev.copy(which = 4)
    dev.off()  
}

foo <- tryCatch({
    .plot(sce)
    .save(
        dir = dir <- "~/desktop",
        fnm = fnm <- "plot1")
}, error = function(e) e)

# plot has been written to PDF!
file.exists(file.path(dir, paste0(fnm, ".pdf")))

# plot not returned
class(foo)

foo <- tryCatch({
    .plot(sce)
}, error = \(e) e)

# plot is stored in variable
class(foo)

# write to file if plotting didn't fail
if (!inherits(foo, "error")) {
    foo
    .save(
        dir = dir <- "~/desktop",
        fnm = fnm <- "plot2")
}

# plot has been written to PDF!
file.exists(file.path(dir, paste0(fnm, ".pdf")))
ramziabb commented 2 years ago

Thanks. Got it working this way in the end. Kind of brute force but it works.


myPlot <- NULL
myPlot <- tryCatch( {
  hm <- plotDiffHeatmap(sce, rowData(da_res1$res), all = TRUE, fdr = FDR_cutoff)
  funColorConditions2(hm)
  hm
}, error=function(e) {
  message("Error in Plot 22.b")
  message(e)
  return(NULL)
})
myPlot

if (!is.null(myPlot)) {
  funWritePlotPDF("Plot 22b. .PDF")
}