Adding dotted line in between two plot windows - r

I wish to produce a plot similar to this. However, I would like the solid line dividing these two windows to be dotted. I've searched around the internet a bit but I still havent found anything useful. Any ideas would be highly appreciated.
layout(matrix(1:2,ncol=1),widths=1,heights=c(2,2),respect=FALSE)
par(mar = rep(0, 4), oma=c(4, 4, 4, 2), las=1)
plot(rnorm(100), type='l', ann=FALSE, xaxt='n')
plot(rnorm(100), type='l', ann=FALSE)
title("Hi", outer=TRUE)
mtext("x-axis", 1, 3, outer=TRUE)
mtext("y-axis", 2, 3, outer=TRUE, las=0)

You could over-write the upper box border of the lower plot with one of these:
abline(h= par("usr")[4], lty=3,col="white",xpd=TRUE, lwd=2)
# there is some bleed-through so to get a definite black-white dotted line needed to repeat the graphics call
corners=par('usr')
replicate(3, segments(x0= corners[1], x1= corners[2],
y0= corners[4], y1= corners[4],
lty=3,col="white",xpd=TRUE, lwd=2) )
Nuts. The png() output is different than the output on the interactive device (quartz()).

Little workaround. Need to figure out where exactly you overplot the border. Would just go with something like this:
set.seed(1234)
par(lty=1)
layout(matrix(1:2,ncol=1),widths=1,heights=c(2,2),respect=FALSE)
par(mar = rep(0, 4), oma=c(4, 4, 4, 2), las=1)
plot(rnorm(100), type='l', ann=FALSE, xaxt='n')
plot(rnorm(100), type='l', ann=FALSE)
par(lty=2)
abline(h=3.27, col="white")
par(lty=1)

Related

Spacing and plot dimensions in R using layout

I'm using the layout function to arrange two plots using the following code:
#Set up layout
m <- matrix(c(1,1,2, 1,1,2), nrow = 3, ncol = 2)
layout(m)
#First plot
plot(data$WG,data$RPOP, pch=21, cex=0.8, col=data$circle, bg=data$fill, xaxt='n', yaxt='n', bty="L", xlab="", ylab="Y label 1",xlim=c(0.02,1), ylim=c(0.02,1))+axis(side=1, at=seq(0,1, .1), pos=-0.02, tck=-.01, labels=FALSE)+axis(side=2, at=seq(0,1, .1), pos=-0.02, tck=-.01, las=1)
#Second plot
datum<-data.frame(prop=c(0.027879, 0.031515,0.001212,0,0,0,0,0,0,0,0),freq=c(0, 0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0))
plot(datum$freq,datum$prop, cex=0, xaxt='n', yaxt='n', bty="L", xlab="X label", ylab="Y label 2", xlim=c(0.02,1), ylim=c(0.001,0.05))+axis(side=1, at=seq(0, 1, 0.1), pos=-0.001, tck=-.01)+axis(side=2, at=seq(0, 0.05, 0.01), pos=-0.02, tck=-.01, las=1)+lines(datum$freq,datum$prop, lwd=2, col="red")
And this is the result I get the following graph:
I would like to get rid of the space between the two graphs and at the same time I would like the width and height of the top plot to be the same. Is there a way to achieve this with the layout function?
Change the margins to get the plots closer together. The default margins are 5.1, 4.1, 4.1, 2.1 in the order bottom, left, top, right. So we'll make the bottom margin smaller for the top plot and the top margin smaller for the bottom plot. To reset the margins to the default after you're done, do par(mar=c(5,4,4,2) + 0.1):
#Set up layout
m <- matrix(c(1,1,2, 1,1,2), nrow = 3, ncol = 2)
layout(m)
# Smaller bottom margin for top plot
par(mar=c(1,4,4,2))
#First plot
plot(data$WG,data$RPOP, pch=21, cex=0.8, col=data$circle, bg=data$fill, xaxt='n', yaxt='n', bty="L", xlab="", ylab="Y label 1",xlim=c(0.02,1), ylim=c(0.02,1))+axis(side=1, at=seq(0,1, .1), pos=-0.02, tck=-.01, labels=FALSE)+axis(side=2, at=seq(0,1, .1), pos=-0.02, tck=-.01, las=1)
#Second plot
datum<-data.frame(prop=c(0.027879, 0.031515,0.001212,0,0,0,0,0,0,0,0),freq=c(0, 0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0))
# Smaller top margin for bottom plot
par(mar=c(5,4,1,2))
plot(datum$freq,datum$prop, cex=0, xaxt='n', yaxt='n', bty="L", xlab="X label", ylab="Y label 2", xlim=c(0.02,1), ylim=c(0.001,0.05))+axis(side=1, at=seq(0, 1, 0.1), pos=-0.001, tck=-.01)+axis(side=2, at=seq(0, 0.05, 0.01), pos=-0.02, tck=-.01, las=1)+lines(datum$freq,datum$prop, lwd=2, col="red")
UPDATE: One way to get a square plot would be to set par(pty="s") (the default is "m"), which gives a 1/1 aspect ratio. However, after you reset par(pty="m") for the second plot, the two plots might not have the same width and you would have to play around with the plot size to get them lined up.
Another option would be to set the output file size to get the desired aspect ratio when you save it to png or pdf. For example:
png("test.png", 600, 800)
... All of your plotting code, including call to layout...
dev.off()
pdf("test.pdf", 6, 8)
... All of your plotting code, including call to layout...
dev.off()
There's probably a programmatic way to ensure the desired aspect ratio and line up the plots correctly without any manual adjustments, but I'm not sure how to do it.

Plotting line graph with factors in R

I am working on this graph in R:
However as you see I am getting these solid dashes instead of nice lines. Here is the code I used to make this graph:
par(mar = c(5,5,2,5))
with(bedtimes, plot(trap, funestus, type="l", col="red3",
ylab=expression(italic(p))),
ylim=c(0,3))
par(new = T)
with(bedtimes, plot(trap, bed, pch=16, axes=F, xlab=NA, ylab=NA, cex=1.2))
axis(side = 4)
mtext(side = 4, line = 3, 'Proportion in bed')
polygon(bedtimes$bed,col=transp("gray", 0.3), border = NA)
And here is the dput of the data I am using:
(removed)
I realise that this is occurring because my x axis is a factor and not numeric. However, trying to change this (e.g. using as.POSIXct(paste0("2016-07-12",bedtimes$trap)) is causing me all sorts of problems, as I had to ake sure R plotted these factors in the correct order originally by using bedtimes$trap <- factor(bedtimes$trap, levels = bedtimes$trap)
How can I produce this same graph but with lines instead of these dashes?
I eventually want a graph that looks similar to this, to give you an idea (though not exactly the same):
Thank you!
As I said in comments, you can try to use the levels of your factor variable:
par(mar = c(5,5,2,5))
with(bedtimes, plot(as.numeric(trap), funestus, type="l", col="red3",
ylab=expression(italic(p))),
ylim=c(0,3))
par(new = T)
with(bedtimes, plot(as.numeric(trap), bed, type="l", axes=F, xlab="", ylab=NA, cex=1.2))
axis(4)
axis(side = 1, at=1:length(levels(bedtimes$trap)), levels(bedtimes$trap))
mtext(side = 4, line = 3, 'Proportion in bed')
polygon(bedtimes$bed,col="gray", border = NA)

Grid doesn't match the axis

I am using the following couple of lines to produce the below plot from rows of two 4X10 Matrix d1, and d2 in one graph:
plot(as.matrix(d1[2,]), as.matrix(d2[2,]), type="o", col="red",
ann=FALSE, pch=17, log = 'y',lty=4, axes=FALSE, las=2) +
lines(as.matrix(d1[1,]),as.matrix(d2[1,]), type="o", col="blue",
ann=FALSE, pch=15, lty=4)
x_axis_labels <- c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
axis(1,labels = x_axis_labels, at = x_axis_labels)
y_axis_labels <- c(3e+4, 6e+4,2e+5,3e+5, 6e+5, 2e+6,5e+6)
axis(2,labels = y_axis_labels, at = y_axis_labels, las=2)
grid()
Which produces the following:
But what I like to have is to have the grid to start from all the labels on each axis. At the moment it only starts from some of the labels on the x-axis, and is not aligned with any of the y-axis labels.
This will probably be easier to control with abline:
abline(v=x_axis_labels, h=y_axis_labels, lty=2, col='lightgray')
If you want the gridlines behind points etc., then try the panel.first argument to plot:
plot(as.matrix(d1[2,]), as.matrix(d2[2,]), type="o", col="red",
ann=FALSE, pch=17, log = 'y',lty=4, axes=FALSE, las=2,
panel.first=abline(v=x_axis_labels, h=y_axis_labels, lty=2, col='lightgray'))

Extending axes to encompass all data in R

I feel like this is a very basic question but I have spent a lot of time looking for an answer and haven't found one. So, if this is answered somewhere else I would love to be redirected rather than downvoted, please.
Anyway, my problem is that when I graph in R, often the y-axis will fail to extend to the end of my data. A sample graphic is below, where you can see that it would be better for the axis to go all the way to 30 rather than 20. However, submitting ylim = c(0,30) doesn't do anything and I cannot think of or find another command that would do the trick?
Here is a reproducible example. If ylim usually works then I am assuming something is breaking because of the aesthetic changes I've made?
set.seed(1)
x<-runif(1:1000, min=1, max=10)
hist(x, breaks=100, main=NA, axes=F, xlab = NA, ylab = NA)
axis(side = 1, tck= -.01, labels=NA)
axis(side = 2, tck=-.01, labels=NA)
axis(side = 1, lwd=0, line= -.4, cex.axis=1.4)
axis(side = 2, lwd=0, line=-.4, las=1, cex.axis=1.4)
mtext(side = 1, "Percent pathogenic bacteria", line = 2.5, cex=1.8)
mtext(side = 2, "Frequency", line = 2.5, cex=1.8)
Use ylim to specify the y axis range:
set.seed(3)
f <- function(y, ...)
hist(y, breaks=20, ...)
ylim <- range(pretty(ceiling(f(y <- rchisq(1000, 3), plot=FALSE)$counts/10)*10))
f(y, ylim=ylim) # versus f(y)

R, plot , font size changes in multiple plot figures

I am creating graphs for a publication and would like them to have the same font size.
When I create a figure with multiple plots, the font size decreases even though I haven't changed the tiff() resolution or pointsize parameter.
I increased the figure size according to ultimately fit the number of plots, and made sure the margins are equivalent for single and multiple plot figures.
Following is an example code (The font size is consistent between 1x1 and 2x1 figure, but decreases for 3x2 figure):
tiff("1x1.tif", width=3,height=2.5,units="in",res=600,pointsize=8,
compression="lzw",restoreConsole=T)
par(mfrow=c(1,1),mar=c(4,4,.5,.5)+0.1)
plot(x=rnorm(10),y=rnorm(10))
dev.off()
tiff("2x1.tif", height=2.5*2,width=3,units="in",res=600,pointsize=8,
compression="lzw",restoreConsole=T)
par(mfrow=c(2,1),mar=c(2,4,2.5,0.5)+0.1)
plot(x=rnorm(10),y=rnorm(10),xaxt="n",xlab="")
par(mar=c(4,4,0.5,0.5)+0.1)
plot(x=rnorm(10),y=rnorm(10))
dev.off()
tiff("3x2.tif", height=2.5*3,width=3*2,units="in",res=600,pointsize=8,
compression="lzw",restoreConsole=T)
par(mfrow=c(3,2),mar=c(.5,4,4,0.5)+0.1)
plot(x=rnorm(10),y=rnorm(10),xaxt="n",xlab="")
par(mar=c(.5,2,4,2.5)+0.1)
plot(x=rnorm(10),y=rnorm(10),xaxt="n",xlab="",yaxt="n",ylab="")
par(mar=c(2.5,4,2,0.5)+0.1)
plot(x=rnorm(10),y=rnorm(10),xaxt="n",xlab="")
par(mar=c(2.5,2,2,2.5)+0.1)
plot(x=rnorm(10),y=rnorm(10),xaxt="n",xlab="",yaxt="n",ylab="")
par(mar=c(4.5,4,0,0.5)+0.1)
plot(x=rnorm(10),y=rnorm(10))
par(mar=c(4.5,2,0,2.5)+0.1)
plot(x=rnorm(10),y=rnorm(10),yaxt="n",ylab="")
dev.off()
Why is this happening?
P.S.: I'm not using ggplot2 or lattice because I'm using my own error bar function on the "actual" figures (I can't remember why right now but I tried working with the ggplot2 error bars and didn't get what I wanted).
The parameter controlling the overall relative size of objects in the plot (including text) is called cex. When you use many panels it is decreased by default, but it can be overridden by manually setting it to 1.
par(mfrow=c(3,2), mar=c(.5,4,4,0.5)+0.1, cex=1)
Off-topic-tip
It looks like you should use oma (outer margin) rather than calling par(mar=...) between the calls to plot. I find it very useful, but hardly anyone seems to know of it. Also ann=FALSE turns off all anotations, las=1 turns axis tick labels horizontal.
par(mfrow=c(3,2), oma=c(4.5, 4, 4, 2.5), mar=rep(.1, 4), cex=1, las=1)
plot(x=rnorm(10), y=rnorm(10), ann=FALSE, xaxt="n")
plot(x=rnorm(10), y=rnorm(10), ann=FALSE, xaxt="n", yaxt="n")
plot(x=rnorm(10), y=rnorm(10), ann=FALSE, xaxt="n")
plot(x=rnorm(10), y=rnorm(10), ann=FALSE, xaxt="n", yaxt="n")
plot(x=rnorm(10), y=rnorm(10), ann=FALSE)
plot(x=rnorm(10), y=rnorm(10), ann=FALSE, yaxt="n")
title("My plot", outer=TRUE)
mtext("X-axis label", 1, 3, outer=TRUE)
mtext("Y-axis label", 2, 3, outer=TRUE, las=0)

Resources