Plotting in R using plot function - r

I am trying to plot few graphs using loops. I am now describing in details.
First I have a function which is calculates the y-variable (called effect for vertical axis)
effect<- function (x, y){
exp(-0.35*log(x)
+0.17*log(y)
-0.36*sqrt(log(x)*log(y)/100))
}
Now I run the following code and use the option par to plot the lines in the same graph. I use axis=FALSE and xlab="" to get a plot without labels. I do this so that my labels are not re-written each time the loop runs and looks ugly.
for (levels in seq(exp(8), exp(10), length.out = 5)){
x = seq(exp(1),exp(10), length.out = 20)
prc= effect(levels,x)
plot(x, prc,xlim = c(0,max(x)*1.05), ylim=c(0.0,0.3),
type="o", xlab = "",ylab = "", pch = 16,
col = "dark blue", lwd = 2, cex = 1, axes = F)
label = as.integer(levels) #x variable
text(max(x)*1.03,max(prc), label )
par(new=TRUE)
}
Finally, I duplicate the plot command this time using the xlab and ylab options
plot(x, prc, xlab = "X-label", ylab = "effect",
xlim = c(0,max(x)*1.05), ylim = c(0,0.3),
type="l", col ='blue')
I have several other plots in the similar lines, using complex equations. I have two questions:
Is there an better option to have the same plot with smoother lines?
Is there an easier option with few lines to achieve the same, where I can place the texts (levels) for each line on the right with white background at the back?

I believe working with the plot function was tedious and time consuming. So, I have finally used ggplot2 to plot. There were several help available online, which I have used.

Related

How change the y-axis numbers to be horizontal on an NMDS plot created in vegan?

Can I change the y-axis numbers to be horizontal on an NMDS plot created in vegan?
library(vegan)
sp <- poop[,28:34]
bat <- poop[,4:7]
mds1 <- metaMDS(sp, k=3,try=200)
plot(mds1$points[,1], mds1$points[,2], pch = as.numeric(bat$species),
col= as.numeric(bat$species),
xlab = "NMDS1", ylab= "NMDS2")
In R, the direction of labels is controlled by graphical parameter las (see ?par). You can also give this parameter in plot call for the metaMDS result. As you see from ?par, las=1 will put all labels horizontal.
More seriously, you should not plot metaMDS results like you do. It is better to use the dedicated plot method for the result, or if you want to do it all by yourself, you should at least force equal aspect ratio for axes with asp = 1 in your plot call. So the following should work:
## with metaMDS plot:
plot(mds1, display="si", las=1, type = "n") # for an empty plot
points(mds1, pch = as.numeric(bat$species), col= as.numeric(bat$species))
## or with generic plot:
plot(mds1$points[,1], mds1$points[,2], pch = as.numeric(bat$species),
col= as.numeric(bat$species),
xlab = "NMDS1", ylab= "NMDS2",
asp = 1, las = 1) # this is new

plotting the legend as a title in two by two layout of base plots in R

My problem is with the legend. The legend is cut off, so it is missing two values. How do I go about moving legends to the title position, while still maintaining correct formating so that everything fits and is aligned to the plot?
My legends are of varying lengths so it would be great to have a way to always have them perfectly line up above the plot.
x<-c(1, 30,60)
y<-c(.001,.023,.03)
data<-cbind(x,y)
N<-100
plot_pdf_1<-function(data, ymax, big){
par(cex=big)
plot(data, type = "l", lwd=2,xaxt="n", yaxt="n", xaxs="i", yaxs="i", ylim=c(0,ymax))
my_at<- c(0,10,20,30,40,50,60,70,80,90) # to specify the tick marks
#initialize all points to zero first
#number of data points
N_o1_male<-0
N_o1_female<-0
N_o139_male<-0
N_o139_female<-0
N_non_male<-0
N_non_female<-0
#subscript format to be used in my legend
my.expressions <-c(as.expression(bquote('N'['1M']*' = '*.( N_o1_male))), as.expression(bquote('N'['1F']*' = '*.( N_o1_female))), as.expression(bquote('N'['2M']*' = '*.( N_o139_male))),as.expression(bquote('N'['2F']*' = '*.( N_o139_female))), as.expression(bquote('N'['3M']*' = '*.( N_non_male))),
as.expression(bquote('N'['3F']*' = '*.( N_non_female))))
par(xpd=TRUE)#to allow legend in outer margins
legend("topleft",legend=my.expressions,inset=c(0,-.11),
text.col="black",box.col=0, bty="n", cex = .75, lty= c( 1,2,1,2,1,2), col = c("purple","purple","blue","blue","black","black"),horiz = TRUE,seg.len = 1)
}
#formatting to plot in a two by two layout
op <- par(mfrow = c(2,2),
oma = c(5,4,0,0) + 0.1,
mar = c(0,0,1,.5) + 0.1)
#calls each plotting function and layout in a two by two
twobytwo<-function(data,ymax,big){
op
plot_pdf_1(data,ymax,big)
plot_pdf_1(data,ymax,big)
plot_pdf_1(data,ymax,big)
plot_pdf_1(data,ymax,big)
title(xlab = "Age (years)",
ylab = "Probability Density",
outer = TRUE, line = 3)}
twobytwo(data, ymax=.04, big=1) #calls the two by two function which lays out four plots in a two by two format. The plots share the same axis.
Three solutions:
Reduce font with cex
Remove the spaces on both sides of the ' = '
Widen your chart. You can set the chart size with win.graph() in
Windows or X11() or quartz() in other OS.
Using win.graph(width=11, h=7) before the op<-... call

R, how to use pch with time series plot

I would like to plot a time series (meaning line graph with x axis as time) and specify a plotting character to use. None of the following has worked
a1 = as.xts(ts(c(5,3,7,2,4,8,3), start=c(1980,1), freq=4))
library('lattice')
xyplot(a1, col="red", pch=2)
xyplot(a1, col="red", par.settings = list(superpose.symbol = list(col = 1, pch = 2)),)
ts.plot(ts(a1), pch=2)
plot(a1, phc=2)
I would prefer a lattice solution, but would accept any solution if lattice can not do this.
By default, time series plots in R use type = "l", which means that you get a line but no point characters. To get both, you can change your type to "b".
xyplot(a1, col = "red", pch = 2, type = "b")
This yields:
The same logic applies to the base plot function; simply add type = "b".

graphing several lines of same function in R

So I am trying to add some graphs to my notes of different functions.
Below is a simple interest function that gives the accumulated value of 1$ at time t with interest rate i. When I plot it, the initial function avSimple(0.075,t) looks fine but the addition ploted lines from the lines command plots the lines red & blue lines one unit to the right.
But they should all have a common point at t = 0, AV = 1.
What is going on here? I'm fairly new to this so I hope this isn't a dumb question.
# AV Simple Interest
avSimple = function(i,t){
av = (1 + (i * t))
return(av)}
t = 0:50
plot(t,avSimple(0.075,t), type="l", main = "AV Simple Interest",
xlab = "Time", ylab = "AV") # This plots good
lines(avSimple(0.05,t), col = "red") #This is shifted to right
lines(avSimple(0.025,t), col = "blue") #This is also shifted right
When using lines you should specify both the x and y values. If you only specify one value, R will assume those are y values and will set x=seq_along(y) (which will start at 1). You should be doing
t = 0:50
plot(t,avSimple(0.075,t), type="l", main = "AV Simple Interest",
xlab = "Time", ylab = "AV") # This plots good
lines(t, avSimple(0.05,t), col = "red") #This is shifted to right
lines(t, avSimple(0.025,t), col = "blue")

Plot line of a function in R

I have the following script:
FGM = function (n,r,z){
x = r*sqrt(n)/(2*z)
Px = 1-pnorm(x)
}
re = 10000
data = data.frame(abs(rnorm(re,0,1)), abs(rnorm(re,0,1)), abs(rnorm(re,0,1)))
colnames(data) = c("n","r","z")
data$Px = FGM(data$n,data$r,data$z)
data$x = data$r*sqrt(data$n)/(2*data$z)
par(mar=c(4.5,4.5,1,1))
plot(data$x,data$Px, xlim = c(0,3), pch = 19, cex = 0.1, xaxs="i", yaxs="i",
xlab = expression(paste("Standardized mutational size (",italic(x), ")")),
ylab = expression(paste("P"[a],"(",italic(x),")")))
Which is a recreation of the graph found here (box 2). You can see in this script that I do this by just plotting 10000 small black points with various values of n,z, and r. This seems like an ugly work around, I think I should just be able to give R my function
FGM = function (n,r,z){
x = r*sqrt(n)/(2*z)
Px = 1-pnorm(x)
}
and have it plot a line on a graph. However, a few hours of scouring the web has been unproductive, and I tried a few ways with abline and lines but nothing worked, is there a way of doing it with these functions or another function?
Tried this...
plot(data$x,data$Px, xlim = c(0,3), ylim = c(0,0.5), xaxs="i", yaxs="i",
xlab = expression(paste("Standardized mutational size (",italic(x), ")")),
ylab = expression(paste("P"[a],"(",italic(x),")")), type = "n")
curve(1-pnorm(r*sqrt(n)/(2*z)), add=T)
>Error in curve(1 - pnorm(r * sqrt(n)/(2 * z)), add = T) :
'expr' must be a function, or a call or an expression containing 'x'
>
#PaulRegular offered this solution but it still plots based on data, not the formula itself. I'm looking for a solution which can produce the curve properly without large values of "re" - using the following but with "re" set to 10 you can see what I mean...
data <- data[order(data$x),]
lines(data$x, data$Px, lwd=1)
You can pass a function of just one variable to plot. I guess that you are looking for:
plot(function(x) 1-pnorm(x),0,3)
Try sorting your data by x, then add the line:
data <- data[order(data$x),]
lines(data$x, data$Px, lwd=2)

Resources