R Function to create several multiple plots - r

I have several multiplots to create, where the difference between them it's just the x and y values of 3 of the four curves of the multiplot.
So one multiplot looks like this:
png(file=paste("~/Documents/plot1.png", sep=""), width=800, height=800 )
plot(xplot1, yplot1, xlab="x1", ylab="y1", type="p", pch=20, cex=0.5, col="yellow", main = "Plot1")
legend("topleft", c("Original curve","Cut curve", "Shifted curve" ), pch=20, cex=0.7, col=c("yellow", "black", "green"))
points(xcutplot1, ycutplot1, type="p", pch=20, cex=0.5, col="black")
points(xsampleplot, ysampleplot, type="p", pch=20, cex=0.05, col="red")
lm.r = lm(ysampleplot ~ xsampleplot)
abline(lm.r)
points(xcutplot1 + shiftX1, ycutplot1 + shiftY1, col="green", type = "p", pch = 20, cex = 0.5)
dev.off()
That works perfectly. My goal now is to create a function where to put the structure of the multiplot above, and then call the function depending on the x and y values of each. So something like this:
getPlot = function(xplot, yplot, xcutplot, ycutplot, shiftX, shiftY){
plot(xplot, yplot, xlab="x", ylab="y", type="p", pch=20, cex=0.5, col="yellow", main = "Plot1")
legend("topleft", c("Original curve","Cut curve", "Shifted curve" ), pch=20, cex=0.7, col=c("yellow", "black", "green"))
points(xcutplot, ycutplot, type="p", pch=20, cex=0.5, col="black")
points(xsampleplot, ysampleplot, type="p", pch=20, cex=0.05, col="red")
lm.r = lm(ysampleplot ~ xsampleplot)
abline(lm.r)
points(xcutplot + shiftX, ycutplot + shiftY, col="green", type = "p", pch = 20, cex = 0.5)
}
And then call the function for each multiplot as:
png(file=paste("~/Documents/plot1.png", sep=""), width=800, height=800 )
getPlot(xplot1, yplot1, xcutplot1, ycutplot1, shiftX1, shiftY1)
dev.off()
png(file=paste("~/Documents/plot2.png", sep=""), width=800, height=800 )
getPlot(xplot2, yplot2, xcutplot2, ycutplot2, shiftX2, shiftY2)
dev.off()
...and so on.
You see that my problem is what to put in return(), since I don't know how to put the plot within a kind of "variable" and then add the other curves to this "variable"...
If I don't put anything in return(), it returns me a plot with only the first curve.
I've not found any solution on the internet, that's why I put the question here to get more ideas...
Thank you in advanced for your help.

Here is the full solution.
Function to create several multiplots:
getPlot = function(xplot, yplot, xcutplot, ycutplot, shiftX, shiftY){
plot(xplot, yplot, xlab="x", ylab="y", type="p", pch=20, cex=0.5, col="yellow", main = "Plot1")
legend("topleft", c("Original curve","Cut curve", "Shifted curve" ), pch=20, cex=0.7, col=c("yellow", "black", "green"))
points(xcutplot, ycutplot, type="p", pch=20, cex=0.5, col="black")
points(xsampleplot, ysampleplot, type="p", pch=20, cex=0.05, col="red")
lm.r = lm(ysampleplot ~ xsampleplot)
abline(lm.r)
points(xcutplot + shiftX, ycutplot + shiftY, col="green", type = "p", pch = 20, cex = 0.5)
}
Some data to call the function:
xplot1 = c(1,2,13,4,15)
yplot1 = c(2,5,14,8,19)
xcutplot1 = c(4,5,6)
ycutplot1 = c(5,8,9)
xsampleplot = c(3,7,4,4,0,4,7,2,11,5,8)
ysampleplot = c(5,7,9,3,2,4,6,7,5,8,10)
shiftX1 = 0.5
shiftY1 = 0.8
Function call:
png(file=paste("~/Documents/plot1.png", sep=""), width=800, height=800 )
getPlot(xplot1, yplot1, xcutplot1, ycutplot1, shiftX1, shiftY1)
dev.off()

Related

Saving plots from R to use with grid.exchange

I would like to make a composite graphic which is 3 panels wide by 8 panels tall. Inside each of the panel would be a graphic that takes multiple R commands to create, like the 1st 3 graphics might be
#1
plot(c(2:20), c(2:20), ylab="", xlab="", axes=FALSE)
par(new=TRUE)
plot(c(1:18, c(1:18), xact="n"), type="l", xlab="", ylab="")
#2
plot(c(2:20), c(2:20), ylab="", xlab="", axes=FALSE)
par(new=TRUE)
plot(c(1:18, c(1:18), xact="n"), type="l", xlab="", ylab="", col=2)
#3
plot(c(2:20), c(2:20), ylab="", xlab="", axes=FALSE, col=3)
par(new=TRUE)
plot(c(1:18, c(1:18), xact="n"), type="l", xlab="", ylab="")
and then I want to use a command like this to display those 3 side by side:
grid.arrange(plot1, plot2, plot3)
I don't understand how to save #1, #2, and #3 each to be plot1, plot2 and plot3. Examples of how to save plots all seem to be based on a single plot command, not multiple commands to make the plot. The help page says grob but doesn't explain what an acceptable grob might be, or how to make it. Should I screenshot each of those and save it as a jpeg file?
thanks for any help.
You can set par(mfrow = c(8, 3)). This will draw each plot in a single panel of an 8 x 3 grid. And will only move on to draw the next plot when plot.new is (implicitly) called.
par(mfrow = c(8, 3))
par(mar = c(0.5, 0.5, 0.5, 0.5)) # Otherwise margins are too large for 24 plots
for(i in 1:24) {
plot(c(2:20), c(2:20), ylab = "", xlab = "", axes = FALSE, col = 3)
par(new = TRUE)
plot(c(1:18), c(1:18), xaxt = "n", type = "l", xlab = "", ylab = "")
}
Update & solution:
Don't use grid.arrange(), don't use jpeg(), recordplot(), pdf() or ggplot...
The below code worked by adding features to the original plots. Then it helps (within RStudio) exporting results as high resolution PNG. I can label the row/columns separately well enough in MS Word.
par(mfrow=c(1,3))
#1
plot1=plot(c(2:20), c(2:20), ylab="", xlab="", axes=FALSE)
par(new=TRUE)
plot1= plot1 + plot(c(1:18, c(1:18), xact="n"), type="l", xlab="", ylab="")
#2
plot2 = plot(c(2:20), c(2:20), ylab="", xlab="", axes=FALSE)
par(new=TRUE)
plot2 = plot2 + plot(c(1:18, c(1:18), xact="n"), type="l", xlab="", ylab="", col=2)
#3
plot3 = plot(c(2:20), c(2:20), ylab="", xlab="", axes=FALSE, col=3)
par(new=TRUE)
plot3 = plot3 + plot(c(1:18, c(1:18), xact="n"), type="l", xlab="", ylab="")

Legend not plotting in chart

I need help with the legend, when I run the code, it doesn't appear.
v_Treasury <- c("DGS5", "DGS10", "DGS30")
getSymbols(Symbols = v_Treasury,
src = "FRED")
I am cleaning the dataset from NA
US5Y<-DGS5["2021/2021"]
US5Y<-na.omit(US5Y)
US10Y<-DGS10["2021/2021"]
US10Y<-na.omit(US10Y)
US30Y<-DGS30["2021/2021"]
US30Y<-na.omit(US30Y)
But the plot has no legend in the graph
plot(US5Y, lwd=2, col="blue",lty = "solid" ,ylab="", xlab="",ylim=c(0.4,3),
main = "US Treasury Yields")
lines(US10Y, col="black", lwd=2, lty="dotted")
lines(US30Y, col="red", lwd=2, lty="dashed")
legend(x="topleft", legend=c("US5Y", "US10Y","US30Y"), col=c("blue", "black", "red"),
lwd=2, lty=c("solid", "dotted","dashed"))
I want to know what is wrong with the code, because the legend is not in the graph
Here is a potential solution:
library(quantmod)
# Data from https://fred.stlouisfed.org/series/DGS5
DGS5 <- read.csv("DGS5.csv")
DGS10 <- read.csv("DGS10.csv")
DGS30 <- read.csv("DGS30.csv")
# the "getSymbols" function from quantmod specifies that
# this is not an 'ordinary' plot - it is an xts 'time-series' plot
# this has implications for e.g. the legend
v_Treasury <- c("DGS5", "DGS10", "DGS30")
getSymbols(Symbols = v_Treasury,
src = "FRED")
US5Y<-DGS5["2021/2021"]
US5Y<-na.omit(US5Y)
US10Y<-DGS10["2021/2021"]
US10Y<-na.omit(US10Y)
US30Y<-DGS30["2021/2021"]
US30Y<-na.omit(US30Y)
# If you turn off clipping ("xpd=NA"), you can see where
# "legend()" is trying to put the legend ("topleft")
par(xpd=NA)
plot(US5Y, lwd=2, col="blue",lty = "solid" ,ylab="", xlab="",ylim=c(0.4,3),
main = "US Treasury Yields")
lines(US10Y, col="black", lwd=2, lty="dotted")
lines(US30Y, col="red", lwd=2, lty="dashed")
legend(x = "topleft", y = NULL, legend=c("US5Y", "US10Y","US30Y"),
col=c("blue", "black", "red"),
lwd=2, lty=c("solid", "dotted","dashed"))
# If you use the "addLegend()" function from the xts package
# then your legend goes where you want it to go
par(xpd=TRUE)
plot(US5Y, lwd=2, col="blue",lty = "solid" ,ylab="", xlab="",ylim=c(0.4,3),
main = "US Treasury Yields")
lines(US10Y, col="black", lwd=2, lty="dotted")
lines(US30Y, col="red", lwd=2, lty="dashed")
addLegend(legend.loc = "topleft", legend.names = c("US5Y", "US10Y","US30Y"),
col=c("blue", "black", "red"), fill=c("blue", "black", "red"), ncol = 1)
Here is a different solution (see the legend.loc option of plot.xts).
library(quantmod)
v_Treasury <- c("DGS5", "DGS10", "DGS30")
getSymbols(Symbols = v_Treasury, src = "FRED")
US5Y <- DGS5["2021/2021"]
US5Y <- na.omit(US5Y)
US10Y <- DGS10["2021/2021"]
US10Y <- na.omit(US10Y)
US30Y <- DGS30["2021/2021"]
US30Y <- na.omit(US30Y)
# Merge the 3 xts objects into one
USdat <- merge(US5Y, US10Y, US30Y, all=TRUE)
# Add a legend using the legend.loc option of plot.xts
plot(USdat, lwd=2,
ylab="", xlab="",ylim=c(0.4,3),
col=c("blue", "black", "red"),
lty=c("solid", "dotted","dashed"),
main = "US Treasury Yields", legend.loc="topright")

Add common legend to multiple pROC plots

I've plotted multiple ROC curves with pROC and now I want to add a common legend horizontally across the bottom-centre of the plot space. I typically use ggplot and now I'm lost with base R plotting.
Here's my code:
# Set plotting parameters
par(mfrow=c(1,2), pty = "s", oma = c(4,1,1,1))
# ROC plot 1
roc(logit_A$y, logit_A$fitted.values, plot=TRUE, legacy.axes=FALSE, percent=TRUE, col="salmon", lwd=2, print.auc=TRUE)
plot.roc(logit_B$y, logit_B$fitted.values, percent=TRUE, col="goldenrod", lwd=2, print.auc=TRUE, add=TRUE, print.auc.y=40)
plot.roc(logit_C$y, logit_C$fitted.values, percent=TRUE, col="lightsteelblue", lwd=2, print.auc=TRUE, add=TRUE, print.auc.y=30)
title(main = "Model 1", line = 2.5)
# ROC plot 2
roc(logit_A2$y, logit_A2$fitted.values, plot=TRUE, legacy.axes=FALSE, percent=TRUE, col="salmon", lwd=2, print.auc=TRUE)
plot.roc(logit_B2$y, logit_B2$fitted.values, percent=TRUE, col="goldenrod", lwd=2, print.auc=TRUE, add=TRUE, print.auc.y=40)
plot.roc(logit_C2$y, logit_C2$fitted.values, percent=TRUE, col="lightsteelblue", lwd=2, print.auc=TRUE, add=TRUE, print.auc.y=30)
title(main = "Model 2", line = 2.5)
# Add legend
legend("bottom",
legend=c("A", "B", "C"),
col=c("salmon", "goldenrod", "lightsteelblue"),
lwd=4, cex =0.4, xpd = TRUE, horiz = TRUE)
How do I make it so the legend is centered along the bottom between both plots?
Do you mean something like this :
m <- matrix(c(1,2,3,3),nrow = 2,ncol = 2,byrow = TRUE)
layout(mat = m,heights = c(0.4,0.4))
for (i in 1:2){
par(mar = c(2,2,1,1))
plot(runif(5),runif(5),xlab = "",ylab = "")
}
par(mar=c(0,0,1,0))
plot(1, type = "n", axes=FALSE, xlab="", ylab="")
plot_colors <- c("blue","green","pink")
legend(x = "top",inset = 0,
legend = c("AUC:72.9%", "AUC: 71.0%", "AUC:80.0%"),
col=plot_colors, lwd=7, cex=.7, horiz = TRUE)

How to create a function that combines 3 plots in one plot using R

I want to combine three plots that I made using the following function
#FUNCTION
dlogistic<-function(k=300,rd=0.599,NO1=2,t=20){
N<-c(NO1,numeric(t))
for(i in 1:t){
N[i + 1] <- N[i] + rd* N[i] * (1-N[i]/k)
}
return(N)
}
#Plot #1
Nts <- dlogistic()
Nts
#Plot #2
K450<-300*1.5
n450=dlogistic(k=K450)
n450
#Plot#3
k05<-300*0.5
n05=dlogistic(k=k05)
n05
The first plot is named Nts, the second, n0450, and the last, n05. Also, I want to use the matplot command somehow.
Here's one using base R. First plot one of them and then add others using lines. Make sure you set the ylim to encompass the whole range of data.
graphics.off()
windows(width = 6, height = 6)
plot(Nts, type = "l", ylim = c(min(Nts, n450, n05), max(Nts, n450, n05)))
lines(n450, type = "l", col = "red")
lines(n05, type = "l", col = "blue")
legend('topleft', legend = c("Nts", "n450", "n05"), lty = 1, col = c("black", "red", "blue"))
With matplot+matlines:
matplot(1:length(Nts), cbind(Nts, n450, n05), pch=19, xlab='x', ylab='y')
matlines(1:length(Nts), cbind(Nts, n450, n05), xlab='x', ylab='y')
legend('topleft', legend=c('Nts','n450','n05'), col=1:3, pch=19, lwd=1, lty=1:3)
With matplot only:
matplot(1:length(Nts), cbind(Nts, n450, n05), type='l', xlab='x', ylab='y')
legend('topleft', legend=c('Nts','n450','n05'), col=1:3, lwd=1, lty=1:3)
With ggplot:
library(ggplot2)
ggplot() +
geom_line(aes(x=1:length(Nts), y=Nts, col='Nts')) +
geom_line(aes(x=1:length(n450), y=n450, col='n450')) +
geom_line(aes(x=1:length(n05), y=n05, col='n05')) +
xlab('x')+
ylab('y')+
theme_bw()

R: plotting untransformed data on a log x axis (similar to plotting on log graph paper)

I have 3 sets of data that I am trying to plot on a single plot. The first data set x values range from ~ 1 to 1700 whereas the other two data sets x values are less than 20. Therefore I want to plot them on a log axis to show variations in all the data sets. However I do not want to transform the data as I want to be able to read the values off the graph. The x axis labels I would like are 1, 10, 100 and 1000 all equally spaced. Does anyone know how to do this? I can only find examples where the data is log as well as the axis. I have attached the code I am currently using below:
Thanks in advance for any help given.
Holly
Stats_nineteen<-read.csv('C:/Users/Holly/Documents/Software Manuals/R Stuff/Stats_nineteen.csv')
attach(Stats_nineteen)
x<-Max
x1<-Min
x2<-Max
y1<-Depth
y2<-Depth
par(bg="white")
par(xlog=TRUE)
plot(x2,y1, type="n", ylim=c(555,0), log="x", axes=FALSE, ann=FALSE)
box()
axis(3, at=c(1,10,100,1000), label=c(1,10,100,1000), pos=0, cex.axis=0.6)
axis(1, at=c(1,10,100,1000), label=c(1,10,100,1000), cex.axis=0.6)
axis(2, at=c(600,550,500,450,400,350,300,250,200,150,100,50,0), label=c
(600,"",500,"",400,"",300,"",200,"",100,"",0), cex.axis=0.6)
mtext("CLAST SIZE / mm", side=3, line=1, cex=0.6, las=0, col="black")
mtext("DEPTH / m", side=2, line=2, cex=0.6, las=0, col="black")
grid(nx = NULL, ny = NULL, col = "lightgray", lty = "solid",
lwd = par("lwd"), equilogs = TRUE)
par(new=TRUE)
lines(x1,y1, col="black", lty="solid", lwd=1)
lines(x2,y2, col="black", lty="solid", lwd=1)
polygon(c(x1,rev(x2)), c(y1,rev(y2)), col="grey", border="black")
par(new=TRUE)
plot(x=Average,y=Depth, type="o",
bg="red", cex=0.5, pch=21,
col="red", lty="solid",
axes=FALSE, xlim=c(0,1670), ylim=c(555,0),
ylab = "",xlab = "")
par(new=TRUE)
plot(x=Mode,y=Depth, type="o",
bg="blue", cex=0.5, pch=21,
col="blue", lty="solid",
axes=FALSE, xlim=c(0,1670), ylim=c(555,0),
ylab = "",xlab = "")
You can do this in ggplot using scale_x_log
so something like:
myplot <- ggplot( StatsNinetee,
aes (x = myResponse,
y = myPredictor,
groups = myGroupingVariable) ) +
geom_point() +
scale_x_log()
myplot
also, avoid attach() it can give odd behavior.

Resources