I'am trying to plot 3 curve in the same plot, but I've got a problem with the third plot relying to bike, it doesn't appear :
Any idea please?
# Define 3 vectors
cars <- c(1, 3, 6, 4, 9)
trucks <- c(2, 5, 4, 5, 12)
bike <- c(12, 15, 14, 15, 12)
# Calculate range from 0 to max value of cars and trucks
g_range <- range(0, cars, trucks)
# Graph autos using y axis that ranges from 0 to max
# value in cars or trucks vector. Turn off axes and
# annotations (axis labels) so we can specify them ourself
plot(cars, type="o", col="blue", ylim=g_range,
axes=FALSE, ann=FALSE)
# Make x axis using Mon-Fri labels
axis(1, at=1:5, lab=c("Mon","Tue","Wed","Thu","Fri"))
Make y axis with horizontal labels that display ticks at every 4 marks. 4*0:g_range[2] is equivalent to c(0,4,8,12).
axis(2, las=1, at=4*0:g_range[2])
# Create box around plot
box()
# Graph trucks with red dashed line and square points
lines(trucks, type="o", pch=22, lty=2, col="red")
lines(bike, type="o", pch=23, lty=3, col="green")
# Create a title with a red, bold/italic font
title(main="Autos", col.main="red", font.main=4)
# Label the x and y axes with dark green text
title(xlab="Days", col.lab=rgb(0,0.5,0))
title(ylab="Total", col.lab=rgb(0,0.5,0))
c("cars","trucks"), cex=0.8, col=c("blue","red"), pch=21:22, lty=1:2);
You could use par(new=TRUE) then set the y-axis to the right side for the third graph.
x <- 1:5
y1 <- rnorm(5)
y2 <- rnorm(5,20)
par(mar=c(5,4,4,5)+.1)
plot(x,y1,type="l",col="red")
par(new=TRUE)
plot(x, y2,,type="l",col="blue",xaxt="n",yaxt="n",xlab="",ylab="")
axis(4)
mtext("y2",side=4,line=3)
legend("topleft",col=c("red","blue"),lty=1,legend=c("y1","y2"))
some sample graph from http://robjhyndman.com/hyndsight/r-graph-with-two-y-axes/
cheers,
Justin
Related
I have been attempting to tilt my x axis labels to 45 degrees. Currently when I run the program, all the titles are stacked on top of each other at each axis.
I expected my code to display my x axis labels at a 45 degree angle, one label per tick, not every label on every tick.
boxplot(x ~ y, data=df, pars=list(xaxt="n") ## boxplot with x axis labels eliminated
axis(1, at=seq(1, 15, by=1), labels=FALSE) ## x axis ticks with no labels
text(seq(1, 15, by=1), par("usr")[3] - 1, labels=df$name, srt=45, pos=1, xpd=TRUE) ## x axis labels at 45 degrees, but they are stacked on top of each other.
Do I need to relabel my dataset, specifically in the df$name? Does the labels=df$name have too many names, which stack on top of each other?
This code is from this source: https://stats.oarc.ucla.edu/r/faq/how-can-i-change-the-angle-of-the-value-labels-on-my-axes/
You just want the unique elements of the names.
Example, using builtin InsectSprays dataset:
boxplot(count ~ spray, data=InsectSprays, xaxt="n")
sq <- seq_along(unique(InsectSprays$spray))
axis(1, at=sq, labels=FALSE)
text(sq, par("usr")[3] - 1.5, labels=unique(InsectSprays$spray),
srt=45, pos=1, xpd=TRUE)
I'm trying to reproduce the plot of the image using this code in R:
N = 1:100
r = 1
K = 1
r1 = list(r*N*(1 - (N/K)))
plot(N, r1[[1]])
but negative values appear on the graph. What am I doing wrong or how can I graph the image?
Thanks in advance
You could use the curve function, which is designed for drawing function curves. In this way, you avoid the detour of generating values in advance.
For the basic curve you just need to code your varying variable N as x:
curve(expr=r*x*(1 - (x/K)), from=1, to=100)
To completely reproduce the plot, we open the R graphics toolbox a little further.
op <- par(mar=c(4, 8, 2, 5)) ## set margins
curve(r*x*(1 - (x/K)), 1, 100,
xlab="", ylab="", xaxt="n", yaxt="n",
axes=FALSE, xaxs="i", yaxs="i",
ylim=c(-8e3, 3e3), lwd=2)
axis(2, labels=FALSE, lwd.ticks=0)
abline(h=-5e3)
text(max(N), -5e3*1.05, "N", font=8, xpd=TRUE)
mtext("r", 2, .5, at=0, las=1, font=8)
mtext("Growth rate", 2, .5, at=2e3, las=1, font=6, cex=1.5)
## for the "K" tick and label in the plot, we need to solve the equation
## to get the intersect with our abitrary x axis at -5e3
f <- function(x, y) r*x*(1 - (x/K)) - y
x.val <- uniroot(f, y=-5e3, lower=0, upper=1000)$root
## and insert the solution as x.value
axis(1, x.val, labels=FALSE, pos=-5e3)
text(x.val, -5e3*1.1, "K", font=8, xpd=TRUE)
par(op) ## reset margins
Result
If you have a look at r1, you'll see that the data are plotted correctly. The values begin at zero and decrease.
If you simply wanted to shift the data for a quick visualization, you can add a scale factor:
#add a scale factor - all values positive
r2<-r1[[1]]+10000
plot(N, r2)
or
#add a scale factor - span y = 0
r3<-r1[[1]]+5000
plot(N, r3)
Add annotation to the plot:
abline(h=0, col="black") #add line at zero
text(65, -600, "K", cex=1.5, col="black") #add text
I am plotting two graphs on the same plot. Each one has a different ylim, and I would like to have the zeroes aligned in the middle of the plot.
This is my code:
# data
time <- seq(0.1, 10, by = 0.1)
det_rot <- runif(100, min=-100, max=100)
vel_mag <- runif(100, min=0, max=5)
# first plot
smoothingSpline = smooth.spline(time, det_rot, spar=0.20)
plot(time, det_rot,lwd=2,
ann=FALSE, las=2, pch="", ylim=c(-100,250)) # , pch=""
lines(smoothingSpline, lwd=2, col="red")
par(new=TRUE)
# second plot
smoothingSpline2 = smooth.spline(time, vel_mag, spar=0.20)
plot(time, vel_mag,
xaxt="n",yaxt="n",xlab="",ylab="",pch="", ylim=c(0,6))
lines(smoothingSpline2, lwd=2, col="blue",)
axis(4)
See the plot:
Simple fix: change ylims to c(-250, 250) and c(-6,6) respectively.
I have plotted the below graph but the cannot adjust the labels of the seconds Y axis. Does anybody have any idea how that is possible?
Also my right hand Y axis has limit from 1 to 14 *10^8 but when I set it, it only goes from zero to 1.4. Cannot find why!
Here is the code I used to make the plot
fdic <- data.frame(matrix(scan(text ="1 16.70833333 1329877000
2 17.20370370 1118256000
3 16.61111111 1047726000
4 19.05555556 972202000
5 15.50925926 269648386
6 0.07407407 248606000
7 3.00925926 220576899
8 5.83796296 188132575"), 8, 3, byrow = T))
colnames(fdic) <- c("id", "botnets_per_wk", "Deposits")
plot <- plot(fdic$id, fdic$botnets_per_wk, pch=16, axes=FALSE, ylim=c(0,25), xlab="", ylab="",
type="l",col="dark blue")
axis(2, col="black",las=1)
mtext("Average # of botnets attacking banks per week",side=2,line=2.5)
box()
par(new=TRUE)
plot(fdic$id, fdic$Deposits, pch=15, xlab="", ylab="", ylim=c(1,1400000000),
axes=FALSE, type="l", col="red")
mtext("Deposits (USD, logged)",side=4,col="red",line=4)
axis(4, ylim=c(1,1400000000), col="black",col.axis="black",las=1)
axis(1,at = seq(1, 50, by = 1))
mtext("bank",side=1,col="black",line=2.5)
legend("topleft",legend=c("Average # of botnets attacking banks per week","Deposits"),
text.col=c("black","red"),pch=c(16,15),col=c("black","red"))
Actually that "1.4" you see is 1.4e+09, the scientific notation for 1.4 billion. Use options(scipen=999) to turn off scientific notation in R (this resets after reboot of R) and then adjust the left margins with par(mai=c(...)) for the long numbers to be completely visible:
fdic <- data.frame(matrix(scan(text ="1 16.70833333 1329877000
2 17.20370370 1118256000
3 16.61111111 1047726000
4 19.05555556 972202000
5 15.50925926 269648386
6 0.07407407 248606000
7 3.00925926 220576899
8 5.83796296 188132575"), 8, 3, byrow = T))
colnames(fdic) <- c("id", "botnets_per_wk", "Deposits")
options(scipen=999)
par(mai = c(1, 1, 1, 2))
plot <- plot(fdic$id, fdic$botnets_per_wk, pch=16, axes=FALSE, ylim=c(0,25), xlab="", ylab="", type="l",col="dark blue")
axis(2, col="black",las=1)
mtext("Average # of botnets attacking banks per week",side=2,line=2.5)
box()
par(new=TRUE)
plot(fdic$id, fdic$Deposits, pch=15, xlab="", ylab="", ylim=c(1,1400000000), axes=FALSE, type="l", col="red")
mtext("Deposits (USD, logged)",side=4,col="red",line=4)
axis(4, ylim=c(1,1400000000), col="black",col.axis="black",las=1)
axis(1,at = seq(1, 50, by = 1))
mtext("bank",side=1,col="black",line=2.5)
legend("topleft",legend=c("Average # of botnets attacking banks per week","Deposits"), text.col=c("black","red"),pch=c(16,15),col=c("black","red"))
But actually I would leave the 1.4-scale and label that axis with "Deposits (in billion US Dollar, logged)", because those long numbers with the many zeros are hard to read (I had to put my finger on them and count the zeros, and you don't want your readers to have to do that).
I am pretty new to R and I managed to create a graph using 'plot' but I forgot error bars and I would like to add them without redoing the whole thing. Does someone know a shortcut?
I calculated the mean by hand because the data set was so small.
Here is the raw data I used and the code to make the graph. I suppose I will need to have R calculate the mean and standard error, but when I try I cant get the graph to look the same.
# Pnem mean occurence each year
Plot9Pn <- c(46, 33, 28)
Plot11Pn <- c(20, 18, 10)
Plot14Pn <- c(34, 28, 26)
Plot15Pn <- c(57, 33, 12)
# Pram mean occurence each year
Plot9Pr <- c(30, 46, 95)
Plot11Pr <- c(8, 11, 14)
Plot14Pr <- c(10, 46, 46)
Plot15Pr <- c(15, 37, 110)
#hand calculated means across plots for each year- to be used in line graph
# Pn2009 <- 39.25
# Pn2010 <- 30.5
# Pn2011 <- 19
# Pr2009 <- 15.75
# Pr2010 <- 35
# Pr2011 <- 66.25
# Define 2 vectors
Pn <- c(39.25, 30.5, 19)
Pr <- c(15.75, 35, 66.25)
g_range <- range(0, Pn,Pr)
plot(Pr, type="o", pch=1, lty=1, col="red", ylim=g_range,
axes=FALSE, ann=FALSE)
lines(Pn, type="o", pch=2, lty=1, col="blue", ylim=g_range,
axes=FALSE, ann=FALSE)
# Make x axis using 2009-2011 labels
axis(1, at=1:3, lab=c("2009","2010","2011"))
# Create a title with a red, bold/italic font
title(main="Mean Yearly Pathogen Levels in Pilarcitos ", col.main="red", font.main=4)
# Label the x and y axes with dark green text
title(xlab="Year", col.lab=rgb(0,0.5,0))
title(ylab="# Positive", col.lab=rgb(0,0.5,0))
# Make y axis with horizontal labels that display ticks at
# every 4 marks. 4*0:g_range[2] is equivalent to c(0,4,8,12).
axis(2, las=1, at=8*0:g_range[2])
# Create box around plot
box()
# Create a legend at (1, g_range[2]) that is slightly smaller
# (cex) and uses the same line colors and points used by
# the actual plots
legend(1, g_range[2], c("P.ramorum","P. nemorosa"), cex=0.8,
col=c("red","blue"), pch=1:2, lty=1);
box()
I think you may have miscalculated the mean of Pn2010.
But if you also hand calculate the standard deviations
Pr.sd <- c(9.946, 16.553, 44.275)
Pn.sd <- c(15.903, 7.071, 9.309
You can add error bars with
arrows(x0=1:3, y0=Pr-Pr.sd, y1=Pr+Pr.sd,
code=3, angle=90, length=.1, col="red")
arrows(x0=1:3, y0=Pn-Pn.sd, y1=Pn+Pn.sd,
code=3, angle=90, length=.1, col="blue")
Here I just add +/- 1 sd. You can calculate them however you like. You might consider offsetting the points as it doesn't look particularly nice.
The arrows function is a base graphics function so it will work with the plotting code you already had. But to make things easier in the future, you'll probably want to look into use a plotting package like ggplot2 or lattice as both of those make plotting with multiple groups much easier and ggplot makes adding error bars easier as well.