I've created a for loop that outputs several plots (via ggplot2) from R into a single .tex file using the tikzDevice package. This makes it easier to include multiple diagrams from within a latex document using a single command that points to the .tex file outputted from R (say 'diagrams.tex'): \include{diagrams}.
However, I would also like to wrap each tikzpicture with the \begin{figure} environment, so that I can insert two additional lines into each respective figure: \caption{} and \label{}.
Question: is there a way to include the figure wrapper, caption, and label latex commands directly, for each respective ggplot image (from my R loop), in the outputted .tex file?
Here is reproducible R code that generates a file 'diagrams.tex' containing 3 ggplots:
require(ggplot2)
require(tikzDevice)
## Load example data frame
A1 = as.data.frame(rbind(c(4.0,1.5,6.1),
c(4.0,5.2,3.5),
c(4.0,3.4,4.3),
c(4.0,8.2,7.3),
c(4.0,2.9,6.3),
c(6.0,3.9,6.6),
c(6.0,1.5,6.1),
c(6.0,2.7,5.3),
c(6.0,2.9,7.4),
c(6.0,3.7,6.0),
c(8.0,3.9,4.2),
c(8.0,4.1,3.5),
c(8.0,3.7,5.8),
c(8.0,2.5,7.5),
c(8.0,4.1,3.5)))
names(A1) = c("state","rmaxpay","urate")
i = 2
## name output file
tikz( 'diagrams.tex' )
for (i in 2:4){ #begin LOOP
st = i*2
df = NULL
df = subset(A1, state == st , select = c(2:3))
print( # start print
ggplot(df, aes(rmaxpay,urate)) + geom_point()
) # end print
} #end LOOP
dev.off()
There may be a way to do this with plot hooks but as it is you can do it by using the console option and sink():
require(ggplot2)
require(tikzDevice)
## Load example data frame
A1 = as.data.frame(rbind(c(4.0,1.5,6.1),
c(4.0,5.2,3.5),
c(4.0,3.4,4.3),
c(4.0,8.2,7.3),
c(4.0,2.9,6.3),
c(6.0,3.9,6.6),
c(6.0,1.5,6.1),
c(6.0,2.7,5.3),
c(6.0,2.9,7.4),
c(6.0,3.7,6.0),
c(8.0,3.9,4.2),
c(8.0,4.1,3.5),
c(8.0,3.7,5.8),
c(8.0,2.5,7.5),
c(8.0,4.1,3.5)))
names(A1) = c("state","rmaxpay","urate")
i = 2
fn <- "diagrams.tex"
if(file.exists(fn)) file.remove(fn)
for (i in 2:4){ #begin LOOP
st = i*2
df = NULL
df = subset(A1, state == st , select = c(2:3))
cat("\\begin{figure}\n", file = fn, append=TRUE)
sink(fn, append=TRUE)
tikz(console = TRUE)
print( # start print
ggplot(df, aes(rmaxpay,urate)) + geom_point()
) # end print
dev.off()
sink()
cat(paste("\\caption{figure}\\label{fig:",i,"}\n",sep=""), file = fn, append=TRUE)
cat("\\end{figure}\n", file = fn, append=TRUE)
} #end LOOP
Related
I am relatively new to R, and it seems that, despite my loops working properly otherwise, I am unable to iterate trough a list to create pdf:
For instance this code
(Variables & libraries:)
Libraries
library(Seurat)
The different markers are lists of chain of characters like DenditicCells:
DendriticCells <- c("Kmo", "Flt3", "Ccr7", "Ccl17", "Irf8","Xcr1","Cd209")
Markers <- list(Neurons, Oligo, OPC, AstroPro, Astro, OligoPro, Pericytes, ImmuneCells, GeneOfInterest, Lymphatics, Vein, Arteries, cappilaries, Microglial, Macrophages, ThCells, Tcells, Bcells, Granulocytes, DendriticCells, CPMicrogenes, TNK, migDCs )
Markers <- setNames(Markers, c("Neurons", "Oligo", "OPC", "AstroPro", "Astro", "OligoPro", "Pericytes", "ImmuneCells", "GeneOfInterest", "Lymphatics", "Vein", "Arteries", "cappilaries", "Microglial", "Macrophages", "ThCells", "Tcells", "Bcells", "Granulocytes", "DendriticCells", "CPMicrogenes", "TNK", "migDCs" ))
Code
pdf(paste0("Run5/DotPlot6", names(Markers[x]),"Subset4.jpeg"))
DotPlot(Subset4, assay = "SCT" ,features =Markers[[x]], dot.scale = 8)
dev.off()
Works and creates a pdf, but this code:
Ret4 <- function(x){
pdf(paste0("Run5/DotPlot6", names(Markers[x]),"Subset4.jpeg"))
try(DotPlot(Subset4, assay = "SCT" ,features =Markers[[x]], dot.scale = 8))
dev.off()
}
for(i in 1:length(Markers))Ret4(i)
fails after a perfectly normal execution. I have tried variation using different format, lapply, map, and it does not work. I do not understand why this execution fails...
How can i iterate through this? In this case, Markers is a list of list of 24 elements.
Thanks a lot
Jean
solution:
Ret5 <- function(x, Markers, Subset, nameSubset){ p <- DotPlot(Subset, assay = "SCT" ,features =Markers[[x]], dot.scale = 8)
png(paste("Run5/Subset/", as.character(x),names(Markers[[x]]),".jpeg", sep = ""))
print(p)
dev.off() }
for(x in c(1:length(Markers))){ Ret5(x, Markers, Subset1, "Subset1")}
I'm trying to optimize the parameters for baseline in the R baseline package by changing each parameters in a loop and comparing plots to determine which parameters give me the best baseline.
I currently have the code written so that the loop produces each plot, but I'm having trouble with getting the plot saved as the class of each object I'm creating is a baseline package-specific (which I'm suspecting is the problem here).
foo <- data.frame(Date=seq.Date(as.Date("1957-01-01"), by = "day",
length.out = ncol(milk$spectra)),
Visits=milk$spectra[1,],
Old_baseline_visits=milk$spectra[1,], row.names = NULL)
foo.t <- t(foo$Visits)
#the lines above were copied from https://stackoverflow.com/questions/37346967/r-packagebaseline-application-to-sample-dataset to make a reproducible dataset
df <- expand.grid(lambda=seq(1,10,1), p=seq(0.01,0.1,0.01))
baselinediff <- list()
for(i in 1:nrow(df)){
thislambda <- df[i,]$lambda
thisp <- df[i,]$p
thisplot <- baseline(foo.t, lambda=thislambda, p=thisp, maxit=20, method='als')
print(paste0("lambda = ", thislambda))
print(paste0("p = ", thisp))
print(paste0("index = ", i))
baselinediff[[i]] <- plot(thisplot)
jpeg(file = paste(baselinediff[[i]], '.jpeg', sep = ''))
dev.off()
}
I know that I would be able to extract corrected spectra using baseline.als but I just want to save the plot images with the red baseline so that I can see how well the baselines are getting drawn. Any baseline users out there that can help?
I suggest you change your loop in the following way:
for(i in 1:nrow(df)){
thislambda <- df[i,]$lambda
thisp <- df[i,]$p
thisplot <- baseline(foo.t, lambda=thislambda, p=thisp, maxit=20, method='als')
print(paste0("lambda = ", thislambda))
print(paste0("p = ", thisp))
print(paste0("index = ", i))
baselinediff[[i]] <- thisplot
jpeg(file = paste('baseline', i, '.jpeg', sep = ''))
plot(baselinediff[[i]])
dev.off()
}
Note that this does not try to capture the already plotted element (thisplot) inside of the list. Instead, the plotting is done after you call the jpeg command. This solves your export issue. Another problem was the naming of the file. If you call baselinediff[[i]] inside of paste, you apparently end up with an error. So I switched it to a simpler name. To plot your resulting list, call:
lapply(baselinediff, plot)
If you are determined on storing the already plotted element, the capture.plotfunction from the imager package might be a good start.
I'm new to R.
I want to add both descriptive statistics and a histogram to a pdf.
The following code successfully generates two histograms using ggplot2. But the describe (from psych package) functions do not appear in the pdf.
How do I include both?
library(psych)
library(foreign)
library(nnet)
library(ggplot2)
library(reshape2)
# direct output to a file
sink("C:\\Users\\jake\\Dropbox\\__iKoda\\datafiles\\OutputR.txt", append=FALSE, split=TRUE)
gc()
memory.limit()
options(max.print=1000000)
results <- read.csv("C:\\Users\\jake\\Dropbox\\__iKoda\\datafiles\\results.csv")
pdf(file="C:\\Users\\jake\\Dropbox\\__iKoda\\datafiles\\plots.pdf")
timesTrimmedComplete=processITStimes(results,"TSICompleted")
print(describe(timesTrimmedComplete$totaltimemins) )
freq=generateQplot(timesTrimmedComplete$totaltimemins,"histogram", 1)
print(freq)
timesTrimmedINComplete=processITStimes(results,"_TSIIncomplete")
print(describe(timesTrimmedINComplete$totaltimemins))
freq1=generateQplot(timesTrimmedINComplete$totaltimemins,"histogram", 1)
print(freq1)
dev.off()
########################################################################################
generateQplot<-function(dataVector, plotType, binWidthValue)
{
freq=qplot(dataVector,geom=plotType, binwidth=binWidthValue)
return(freq)
}
processITStimes<-function(resultsData, statusCode)
{
completeResults <- resultsData[grep(statusCode, resultsData$Final_Status), ]
times <- completeResults[, grep("*duration*", colnames(completeResults))]
times[is.na(times)] <- 0
times$totaltime <- rowSums( times[,2:ncol(times)] )
times$totaltimemins <-round(times$totaltime/60, digits=0)
times$rowId<-completeResults$RowId
print(statusCode);
print(describe(times$totaltimemins) )
timesTrimmed<-times[times$totaltimemins<60,]
return(timesTrimmed)
}
sink()
If you're making ggplots, you can always use ggsave(). So you'd do
ggsave(plot = freq1, filename = "freq1.pdf", device = "pdf")
You can also specify how large to make the plot (height/width/units), etc.
I have created 36 heatmaps with the function pheatmap, and I want to display them in just one figure. I have tried to using the function par(), but it did not work, I do not know why. Could someone tell me what should I do? Thank you very much. This is my code:
require(graphics);require(grDevices);library("pheatmap", lib.loc="D:/Program Files/R/R-3.1.1/library");library(gplots)
filenames<-list.files("D:/Project/bladder cancer/heatmap0829/heatmap/"); # detect all of the files in the fold
filename2<-strtrim(filenames,nchar(filenames)-4); # all of the filenames without extension names
par(mfrow=c(18,2)) #divide the graphics windows into a 18x2 matrix
for(i in 1:length(filename2)){
rt<-read.table(paste("D:/Project/bladder cancer/heatmap0829/heatmap/",filenames[i],sep = ""), header = T, sep = '\t') # Import the data with the ith file name
size=dim(rt) # the dimensional of the datafram
cw=400/size[1] #the width of the cell in the heatmap
rt<-log10(rt)
x <- t(data.matrix(rt))
pheatmap(x,color=greenred(256),main=filename2[i],cluster_rows = F, cluster_cols = T,cellwidth = cw, cellheight = 60,border_color =F,fontsize = 8,fontsize_col = 15)}
This is one dataset
ScaBER 5637
1 1.010001e+02
1.341186e+00 2.505067e+01
1.669456e+01 8.834190e+01
7.141351e+00 3.897474e+01
1.585592e+04 5.858210e+04
1 3.137979e+01
1.498863e+01 7.694948e+01
1.115443e+02 3.642917e+02
1.157677e+01 5.036716e+01
4.926492e+02 8.642784e+03
3.047117e+00 1.872154e+01
I have 36 txt files like this, but I can not put all of them here
"ScaBER 5637" is the column name of this dataset
See this previous answer: Histogram, error: Error in plot.new() : figure margins too large
par(mfcol=c(3,12), oma=c(1,1,0,0), mar=c(1,1,1,0), tcl=-0.1, mgp=c(0,0,0))
for(i in 1:36){
plot(runif(2), runif(2), type="l")
}
dev.off()
I am generating plot in R and save it as PDF with:
pdf(
file='Plots/errors.pdf',
height=4,
width=7,
onefile=TRUE,
family='Helvetica',
pointsize=12
)
# Here is my graphics
dev.off()
Somewhere inside graphics I have:
mtext(
expression(mu[H1])
)
It produces neat PDF with correctly processed greek letter µ.
Then I import this PDF in LaTeX article with:
\includegraphics[width=1\textwidth,height=0.4\textheight]{../Plots/errors.pdf}
But instead of µ sign of infinity (∞) is displayed.
Why?
For seamless integration without the encoding issues, I would look at package 'TikzDevice'. It outputs Tikz images in LaTeX format. For example:
require(tikzDevice)
setwd("/Path/To/LaTeX/Files/")
#Names of LaTeX symbols
syms <- c('alpha', 'theta', 'tau', 'beta', 'vartheta', 'pi', 'upsilon', 'gamma', 'varpi', 'phi', 'delta', 'kappa', 'rho', 'varphi', 'epsilon', 'lambda', 'varrho', 'chi', 'varepsilon', 'mu', 'sigma', 'psi', 'zeta', 'nu', 'varsigma', 'omega', 'eta', 'xi', 'Gamma', 'Lambda', 'Sigma', 'Psi', 'Delta', 'Xi', 'Upsilon', 'Omega', 'Theta', 'Pi', 'Phi')
len <- length(syms)
# random colors (red, green, blue)
r <- round(runif(len), 2)
g <- round(runif(len), 2)
b <- round(runif(len), 2)
# calculate dummy data points
x <- runif(50,1,10)
y <- x + rnorm(length(x))
fit <- lm(y ~ x)
rsq <- summary(fit)$r.squared
rsq <- signif(rsq,4)
# plot the result, will create symbol-regression.tex in the working
# directory the first time this is run it may take a long time because the
# process of calulating string widths for proper placement is
# computationally intensive, the results will get cached for the current R
# session or will get permenantly cached if you set
# options( tikzMetricsDictionary='/path/to/dictionary' ) which will be
# created if it does not exist. Also if the flag standAlone is not set to
# TRUE then a file is created which can be included with \include{}
tikz('symbolr.tex', width = 4,height = 4,pointsize = 12)
# The syntax is mar=c(bottom, left, top, right).
par(mar=c(2,2,2,2))
# plot the box and the regression line
plot(x, y, type='n', xlab='', ylab='')
box()
abline(fit)
# add the latex symbols as points
text(x, y, paste('\\color[rgb]{',r,',',g,',',b,'}{$\\',syms,'$}',sep=''))
# Display the correlation coefficient
mtext(paste("Linear model: $R^{2}=",rsq,"$" ),line=0.5)
# and the equation of the line
legend('bottom', legend = paste("$y = ", round(coef(fit)[2],3),'x +', round(coef(fit)[1],3), '$', sep=''), bty= 'n')
# Close the device
dev.off()
Then all you have to do is include the file just output from R in your LaTeX document.