Adding text to different panels in lattice when scales are separate? - r

I would like to add text labels (e.g. a, b, c, d) to different panels in a lattice multi panel plot. I would like the text to appear at the same point (i.e. in the top left corner) in each plot, however I can't seem to do this when the scales are not constant.
library(lattice)
X <- rnorm(100)
Y <- rnorm(100)
n <- c(rep("control", 5), rep("low", 5), rep("medium", 5),
rep("high", 5), rep("v.high", 5))
Z <- c(rep("a", 25), rep("b", 25), rep("c", 25), rep("d", 25))
df1 <- data.frame(X, Y, n, Z)
MyText <- c("(c)", "(d)", "(a)", "(b)")
xyplot(X ~ Y|Z, data=df1,
groups=n,
panel=function(x, y,...){
panel.xyplot(x, y,...)
panel.text(-1, 1.5, labels=MyText[panel.number()])
},
ylab = expression(paste(delta, ""^"15", "N")),
xlab = expression(paste(delta, ""^"13", "C")),
scales=list(relation="free"),
strip = F,
auto.key=list(columns= 5, title="Treatments", cex.title=1))
If anybody has any advice on this your help would be much appreciated.

One way is with grid.text, referring to the desired location with npc coordinates, where the lower left corner is (0, 0), and the upper right is (1, 1).
library(grid)
xyplot(X~Y|Z, data=df1,
groups=n,
panel=function(x, y,...) {
panel.xyplot(x,y,...)
grid.text(MyText[panel.number()], unit(0.05, 'npc'), unit(0.95, 'npc'))
},
ylab = expression(paste(delta, ""^"15","N")),
xlab = expression(paste(delta, ""^"13","C")),
scales=list(relation="free"),
strip = F,
auto.key=list(columns= 5, title="Treatments", cex.title=1))

Related

How to move y-axis labels away from R plot using lapply in R

I have the following code (Thanks to an answer from #Rawr in this question):
labes1 <- c("P(LNG)","","Volume(LNG)","","P(oil)","","Can.GDP","","US GDP","")
titles <- c("Levels","","","","","Log Difference","","","","")
par(mfrow = c(5, 2), mar = c(0.3, 6, 0, 2), oma = c(5, 0, 3, 2))
lapply(1:10, function(ii) {
x <- plotdata1[, ii, drop = FALSE]
plot(x, xlab = "Quarter", ylab = labes1[ii], axes = FALSE)
axis(2, las = 1)
box()
if (ii %in% 9:10) {
axis(1)
title(xlab = 'Quarter', xpd = NA)
}
if (ii %in% 1:2)
title(main = c('Levels', 'Log Difference')[ii], xpd = NA, line = 1)
})
This produces the following plot:
The obvious issue is the overlaying of the y-axis labels with the y-axis values. I have tried playing around with the mar() and oma() but these just change the margins around, I was hoping this would move things out of the way. How can I move the y-axis labels as separate from the plot? I will also be moving the margins a bit so that the white space between the two columns of plots will be closer together.
You can define the ylab separately, like what you're doing for the xlab, and set the line parameter to define its distance from the plot (as stated in this post).
I got a running example from combining your code and #rawr's from your previous question.
set.seed(1)
z <- ts(matrix(rt(200 * 10, df = 3), 200, 10), start = c(1961, 1), frequency = 12)
z <- z * 1e5 # to make "wide" y-axis labels
## vectors of x, y, and main labels
xl <- sprintf('x label %s', 1:10)
yl <- sprintf('y label %s', 1:10)
ml <- sprintf('main label %s', 1:10)
labes1 <- c("P(LNG)","","Volume(LNG)","","P(oil)","","Can.GDP","","US GDP","")
titles <- c("Levels","","","","","Log Difference","","","","")
par(mfrow = c(5, 2), mar = c(0.3, 6, 0, 2), oma = c(5, 0, 3, 2))
lapply(1:10, function(ii) {
x <- z[, ii, drop = FALSE]
plot(x, xlab = "Quarter", ylab = "", axes = FALSE) # set ylab to ""
axis(2, las = 1)
title(ylab = labes1[ii], line = 4) # set the line at an appropriate distance
box()
if (ii %in% 9:10) {
axis(1)
title(xlab = 'Quarter', xpd = NA)
}
if (ii %in% 1:2)
title(main = c('Levels', 'Log Difference')[ii], xpd = NA, line = 1)
})
The code above outputs the following graph for line = 4 :
and this plot for line = 3 :

Overlaying and staggering two plots with different y axes

I am looking for advice for plotting 2 similar wave forms with different y axes scales (one is mmHg and another is m/s) in the same plot. However, I would like to stagger the plots with respect to each other.
For example, using the below:
set.seed(123)
y <- sin(2*pi*x)
g <- sin(2*pi*x)+ rnorm(200, sd=0.1)
plot(y,type="l",
ann = F,
axes = F)
axis(side = 2)
par(new = T)
plot(g,type="l",
ann = F,
axes = F)
axis(side = 4)
Gives:
I would like to achieve something like this (see link below):
How to achieve this?
Here's a slightly cheaty solution:
x <- seq(from = 1, to = 3, by = 0.01)
y <- sin(2*pi*x)
set.seed(123)
g <- sin(2*pi*x)+ rnorm(length(x), sd=0.1)
stagger <- 2
glabels <- c(-1, 0, 1)
plot(c(min(y),max(y)+stagger) ~ c(1,length(y)), type="n", axes=FALSE, ann=FALSE)
lines(y)
axis(side = 2, at = min(y):max(y))
par(new = T)
lines(g+stagger)
axis(side = 4, at = glabels + stagger, labels = glabels)
Results in:
There's probably a better way to generate the positions and labels for the y-axis for g.

plotting more than one data set in R using xyplot

I'd like to plot multiple data sets on this graph but I can't figure out how.
I need to put t, u, v, w on the already functioning xyplot.
library(lattice)
x <- rnorm(250, 5, .5)
y <- rnorm(250, 5, .4)
t <- rnorm(200, 6, .7)
u <- rnorm(200, 6, .6)
v <- rnorm(150, 7, .9)
w <- rnorm(150, 7, .8)
xyplot(y ~ x, xlab="", ylab="",
par.settings = list(axis.line = list(col="transparent")),
panel = function(x, y,t,u,...) {
panel.xyplot(x, y, col=3, pch=16)
panel.rug(x, y, col=8, x.units = rep("snpc", 2), y.units = rep("snpc",
2), ...)})
If you're looking to make a scatter plot of points whose coordinates are defined by (x, y), (t, u), & (v, w), the following should work for you:
df <- data.frame(V1 = c(x, t, v),
V2 = c(y, u, w),
V3 = c(rep("xy", length(x)), rep("tu", length(t)), rep("vw", length(v))))
xyplot(V1 ~ V2, group = V3, data = df,
xlab="", ylab="",
par.settings = list(axis.line = list(col="transparent")),
panel = function(x, y, groups...) {
panel.xyplot(x, y,
col = c("red", "blue", "green"), # change this if you want other colours
pch=16)
panel.rug(x, y, col = 8, x.units = rep("snpc", 2), y.units = rep("snpc", 2))
})
If you're looking to plot them into the chart in some other way, please clarify in your question.

Set color segments by group

I am trying to made a kind of xyplot with a line from the bottom till the value. The problem is that I don't know how to adjust the color of the line.
time <- rnorm(50, 5, 2)
death.count <- rnorm(50, -0.25, 0.25)
Inoc.size <-rep(c("A", "B"), times=25)
data <- data.frame(time, death.count, Inoc.size)
xyplot(death.count ~ time, data,
groups=Inoc.size, ylim=c(0, -0.5),
xlab=list("Time - h", cex=1.5),
ylab=list(expression("Death cells - ln N"[i]), cex=1.5),
par.settings=list(
alpha=0.5,
superpose.symbol=list(pch=c(15, 16, 17, 18),
col=c(myColours[3], myColours[6], myColours[4], myColours[7]))),
auto.key=T,
panel=panel.superpose,
panel.groups=function(x, y, col, group.number, groups, ...) {
xj <- jitter(as.numeric(x), factor=0.5)
panel.xyplot(xj, y, ...)
panel.segments(x0=xj, x1=xj, y0=0, y1=y, groups, lwd=2)
}
)
I don't quite see how your plot matches with your code.
But this may work for you. Define col within panel.groups and reference that indexed by group.number in panel.segments.
library(lattice)
myColours=1:7
time<- rnorm(50,5,2)
death.count<- rnorm(50,-0.25,0.25)
Inoc.size<-rep(c("A","B"),times=25)
data<-data.frame( time,death.count, Inoc.size)
xyplot(death.count~time, data,
groups=Inoc.size,#ylim=c(0,-0.5),
xlab = list("Time - h", cex=1.5),
ylab = list(expression("Death cells - ln N"[i]), cex=1.5),
par.settings= list(
alpha = 0.5,superpose.symbol=list(
pch=c(15,16,17,18),
col=c(myColours[3],myColours[6],myColours[4],myColours[7])),
pch=c(15,16,17,18),
col=c(myColours[3],myColours[6],myColours[4],myColours[7])),
auto.key=T,
panel = panel.superpose,
panel.groups = function(x, y, col,group.number,groups, ...) {
xj=jitter(as.numeric(x), factor=0.5)
col=c(myColours[3],myColours[6],myColours[4],myColours[7])
panel.xyplot(xj,y,...)
panel.segments(x0=xj,x1=xj, y0=0, y1=y,col=col[group.number],groups,
lwd = 2)
}
)
I think you need col=c(myColours[3],myColours[6],myColours[4],myColours[7]) to the panel.segments.
panel.segments(x0=xj,x1=xj, y0=0, y1=y,groups,lwd = 2, col=c(myColours[3],myColours[6],myColours[4],myColours[7]))

Title on a multi-panel plot

The following code works perfectly, except for the last line, which appears to be ignored. The code creates a dataframe consisting of three columns and then proceeds to plot the columns on a 2x2 grid. The last line is supposed to give a title to the entire multi-panel plot. However, it has no effect on the outcome. What is wrong? How can I correct it?
p <- c(3, 5, 10, 20, 50, 100)
n <- c(100, 5000, 100000)
f <- function(x, y){ return ((1 - 2^(-1/y))^(1/x))}
d <- as.data.frame(outer(p, n, FUN = f))
dimnames(d) <- list(p, n)
par(mfrow = c(2,2))
lapply(colnames(d),
function(x) plot(p, d[,x], type = "b",
main = paste("#points = ", x),
xlab = "Dim",
ylab = "Med Dist"))
mtext("Densities", outer = TRUE, cex = 1.5)
Try
par(oma = c(0, 0, 2, 0))
par(mfrow = c(2,2))
lapply(colnames(d),
function(x) plot(p, d[,x], type = "b",
main = paste("#points = ", x),
xlab = "Dim",
ylab = "Med Dist"))
title("Densities", outer=TRUE)

Resources