TIFF file will save but is blank in conditional statement (if statement) - r

I am having an issue with a TIFF files saving, but the graph does not have any content in it. This is specifically happening with an if statement.
if (RMCAv_Graph == T){
Save_Path = file.path(Sub_Folder_Path, "RMCAv.tiff")
tiff(file = Save_Path, units = "in", width = 5, height = 5, res = 600)
RMCAv_Plot
dev.off()
}
I tried to put it into the conditional statement and without the graph. When I put the if statement in the graph, it will not populate as expected.

If you are writing to file inside of a conditional statement, you need to directly tell it to print.
if (RMCAv_Graph == T){
Save_Path = file.path(Sub_Folder_Path, "RMCAv.tiff")
tiff(file = Save_Path, units = "in", width = 5, height = 5, res = 600)
RMCAv_Plot %>% print()
dev.off()
}
or without the pipe:
if (RMCAv_Graph == T){
Save_Path = file.path(Sub_Folder_Path, "RMCAv.tiff")
tiff(file = Save_Path, units = "in", width = 5, height = 5, res = 600)
print(RMCAv_Plot)
dev.off()
}

Related

How to define printing whole graph in ggplot2?

I am using a package called microbiomeMarker to plot a cladogram (ggtree). It was taking too long to print so I implemented the Cairo package so that the printing is faster (there's a considerable change thankfully.
cladogram<-plot_cladogram(
OTU_lefse_res,
color = c("#7570B3","#D95F02"),
only_marker = TRUE,
branch_size = 0.2, #beyond this point everything is default values
alpha = 0.2,
node_size_scale = 1,
node_size_offset = 1,
clade_label_level = 4,
clade_label_font_size = 4,
annotation_shape = 22,
annotation_shape_size = 5,
group_legend_param = list(),
marker_legend_param = list()
)
ggsave(
filename = "16S_Marker_Cladogram.png",
units = "px",
dpi = 300,
type = "cairo-png"
)
My issue is that when it gets saved, the graph is zoomed in (as far as I can figure to the bottom right corner of the legend) so I can't see the cladogram. I've also tried saving it as a pdf, changing the dpi to 900, defining the size by pixels, setting in the ggplot "coord_fixed()"... I'm at a loss, I googled the issue but I can't find anyone having a similar issue. The example data of the package works fine. I've got about 10x the amount of data to be plotted, so I expect some delay, but I don't understand why I can't get it right.
If I don't set a printing device and just do:
plot_cladogram(
OTU_lefse_res,
color = c("#7570B3","#D95F02"),
only_marker = TRUE,
branch_size = 0.2,
alpha = 0.2,
node_size_scale = 1,
node_size_offset = 1,
clade_label_level = 4,
clade_label_font_size = 4,
annotation_shape = 22,
annotation_shape_size = 5,
group_legend_param = list(),
marker_legend_param = list()
)
I don't get any output in the plot window. Any ideas of something else I can try?

How can I add a baseplot with no fixed values to a document

I want to add a baseplot to a word document.
In the documentation for the officer package there's an example that uses the plot_instr function:
anyplot <- plot_instr(code = {
barplot(1:5, col = 2:6)
})
doc <- read_docx()
doc <- body_add(doc, anyplot, width = 5, height = 4)
print(doc, target = tempfile(fileext = ".docx"))
I want to add a plot to a word document inside a function so I need variable input for the plot function like this:
x=1:5
cols=2:6
anyplot <- plot_instr(code = {
barplot(x,col=cols)
})
doc <- read_docx()
doc <- body_add(doc, anyplot, width = 5, height = 4)
print(doc, target = tempfile(fileext = ".docx"))
But the code above doesn't work and I can't find any other examples of plot_instr usage.
I think I found a solution!
When I set a breakpoint before the barplot(...) call, I could see the code when body_add is called with a plot_instr wrapper function. The code creates a temporary png file. I copied this code and adapted it:
x=1:5
cols=2:6
doc <- read_docx()
file <- tempfile(fileext = ".png")
options(bitmapType = "cairo")
png(filename = file, width = 5, height = 5, units = "in", res = 300)
tryCatch({
barplot(x,col=cols)
}, finally = {
dev.off()
})
on.exit(unlink(file))
value <- external_img(src = file, width = 5, height = 5)
body_add(doc, value)
print(doc, target = tempfile(fileext = ".docx"))
The code is generating the following error
Error in barplot.default(x, col = cols) :
'height' must be a vector or a matrix
The issue here is that function body_add has an argument x and you are defining an x before the call. Changing the name to something else solves the issue:
z <- 1:5
cols=2:6
anyplot <- plot_instr(code = {
barplot(z, col = cols)
})
doc <- read_docx()
doc <- body_add(doc, anyplot, width = 5, height = 4)
print(doc, target = "temp.docx")

fastest way to create xlsx with plots R

I have list of data and list of plots which I want two write to xlsx file (each element to separate sheet). Example data:
require(ggplot2)
require(data.table)
n <- 10
N <- 100
dtList <- lapply(1:n, function(x) data.table(sample(1e6, N), 1:N))
names(dtList) <- 1:n
plots <- lapply(dtList, function(x) ggplot(x, aes(y = V1, x = V2)) + geom_line())
Currently I use openxlsx, but it is quite slow for multiple plots:
require(openxlsx)
wb <- createWorkbook()
modifyBaseFont(wb, fontSize = 10)
writeXlsx <- function(x, sName) {
addWorksheet(wb, sName, gridLines = FALSE)
writeData(wb, sName, x = x, xy = c(1, 1))
print(plots[[sName]])
insertPlot(wb, sName, width = 19, height = 9, dpi = 200, units = "cm",
startRow = 2, startCol = 5)
}
system.time(
sapply(seq_along(dtList), function(x) {
writeXlsx(dtList[[x]], names(dtList)[[x]])
})
) # ~ 17.00 sek
openXL(wb)
How could I increase speed of this? Is there a better package to accomplish this?
One options is to use simpler graphics. For example, changing plots to base graphics, like:
plots <- lapply(dtList, function(x) plot(x$V2, x$V1, type = 'l'))
reduces the xlsx creation time to ~0.72 seconds vs ~7.78 seconds (original code works now faster than before), that is around 10 times faster.
When ggplot graphics are needed, I modified insertPlot function to accept this type of object and save it to file without needing to print in R session (using ggsave):
insertggPlot <- function(wb, sheet, width = 6, height = 4, xy = NULL,
startRow = 1, startCol = 1, fileType = "png",
units = "in", dpi = 300, PLOT) {
od <- getOption("OutDec")
options(OutDec = ".")
on.exit(expr = options(OutDec = od), add = TRUE)
if (!"Workbook" %in% class(wb)) stop("First argument must be a Workbook.")
if (!is.null(xy)) {
startCol <- xy[[1]]
startRow <- xy[[2]]
}
fileType <- tolower(fileType)
units <- tolower(units)
if (fileType == "jpg") fileType = "jpeg"
if (!fileType %in% c("png", "jpeg", "tiff", "bmp"))
stop("Invalid file type.\nfileType must be one of: png, jpeg, tiff, bmp")
if (!units %in% c("cm", "in", "px"))
stop("Invalid units.\nunits must be one of: cm, in, px")
fileName <- tempfile(pattern = "figureImage",
fileext = paste0(".", fileType))
ggsave(plot = PLOT, filename = fileName, width = width, height = height,
units = units, dpi = dpi)
insertImage(wb = wb, sheet = sheet, file = fileName, width = width,
height = height, startRow = startRow, startCol = startCol,
units = units, dpi = dpi)
}
Using this, reduces time to ~2 sek.

Write several statements into an anonymous function in R

I want to include a plot into some MS Word document using the reporteRs library.
Here is how I include my plot :
doc = addPlot(doc,
fun = function() plot(
km.as.one,
mark.time=TRUE,
conf.int=FALSE,
cex=1,
col="blue",
xlab = "Délai en années", ylab = "Pourcentage",
lty=1:3,
),
vector.graphic = TRUE, width = 5, height = 4,
par.properties = parProperties(text.align = "center")
)
My problem is that I would like to add some error bars, customize the axis and maybe add the title, by adding something like following :
axis(1, at = seq(0, 36, by = 6))
with (data=summary.km.as.one, expr=errbar(time, surv, upper, lower, add=TRUE, pch=0.5, cap=0.02))
I have to write this outside of the plot statement, but I couldn't find how to write it in the anonymous function.
Is it even possible to write several statements in an anonymous function ?
If yes, what is the right way, and if not, is there any workaround ?
Just add braces { } and you can add multiple lines:
doc = addPlot(doc,
fun = function() {
# line 1
# line 2
# etc...
},
vector.graphic = TRUE, width = 5, height = 4,
par.properties = parProperties(text.align = "center")
)

multiple files for reading and saving

I have multiple files to read and also do heatmap after which the outputs will be saved. Somehow, there is a problem(s) with my code below and I can't figure out why it is not working. Files: mxn.dat, scu.dat, emun.dat, ser.dat
files <- list.files(pattern=".dat")
for (i in length(files)){
data <-read.table(files[i],row.names=1,header=T,sep='\t')
for in length(files){
png('i.png')
pheatmap(t(data[i]), cellwidth = 32, cellheight = 14, fontsize = 5, show_colnames = T, cluster_cols = FALSE)
dev.off()
}
}
Any help will be appreciated to get the code working.
Thanks
Rob
Not a reproducible example so I have no way to test if this will work (and somehow I think that this is too localised to be useful to future visitors), but perhaps try this...
files <- list.files(pattern=".dat")
for (i in 1:length(files)){
data <-read.table( files[i],row.names=1,header=T,sep='\t')
png( paste0( i , '.png' ) )
pheatmap( t( data ), cellwidth = 32, cellheight = 14, fontsize = 5, show_colnames = T, cluster_cols = FALSE)
dev.off()
}
Variation of SimonO101's solution:
files <- list.files(pattern=".dat")
for( f in files )
{
data <-read.table( f, row.names = TRUE, header = TRUE, sep = '\t' )
png( gsub( "pdf", "png", f ) )
pheatmap( t( data ), cellwidth = 32, cellheight = 14, fontsize = 5, show_colnames = T, cluster_cols = FALSE)
dev.off()
}
Easier to read (I believe) and has the advantage (?) of preserving the original file names, only changing the extension.

Resources