1
votes

I’d like to graph some data as means of groups over time, with lines connecting the different mean time points for each group.

The code for this is:

line<-ggplot(dat, aes(Time, Cortisol.ngmL, shape=T))

line+
stat_summary(fun.y=mean, geom="point", size=4, aes(group=T))+
stat_summary(fun.y=mean, geom="line", aes(group=T), linetype="dashed", lwd=0.7)

But…I want the y axis logged (log10). And when I do this the lines connecting the groups across time become curved (code below)

line<-ggplot(dat, aes(Time, Cortisol.ngmL, shape=T))

line+
stat_summary(fun.y=mean, geom="point", size=4, aes(group=T))+
stat_summary(fun.y=mean, geom="line", aes(group=T), linetype="dashed", lwd=0.7)+
coord_trans(y="log10")

Does anyone know a way I can have a log scale and straight lines?

1
We can't see your data, so without knowing what it looks like, it's hard to give a definite answer. My best guess is that the graph is correct. For a log scale, the data need to follow an exponential curve to be straight. Perhaps your data are not exponention? - Joel Carlson
It's an interesting problem - how to plot a straight line between two points on a logarithmic axis. Here's how I did it with a specific example but I'm not at all sure how to generalise that for any two points. The red line is straight on a normal scale. The blue line has been munged to look straight on the logarithmic scale. library(ggplot2); x <- seq(from=1, to=10, by=0.1); ggplot() + geom_line(aes(x = x, y = x), colour = "red") + geom_line(aes(x = (9/log10(10))*log10(x) + 1, y = x), colour = "blue") + coord_trans(y="log10") No idea how to generalise that for any two points though - Mist

1 Answers

1
votes

I use this function to connect points with straight lines in log scale:

log_line <- function(x, y, n = 1000) {
  l <- lapply(2:length(x),
              function(i, n) {
                xl <- seq(x[i - 1], x[i], (x[i] - x[i - 1]) / n)
                yl <- exp(log(y[i]) + (xl - x[i]) * (log(y[i]) - log(y[i - 1])) / (x[i] - x[i - 1]))
                return(data.frame(x = xl, y = yl))
              },
              n)

  return(do.call(rbind, l))
}

The arguments are the x and y coordinates of the points you want to connect with a straight line in log scale and the n number of points you want to predict between each pair of original points.

This function fits a straight line in log scale between each points, predicts n new points between the two original points and than converts them back to the original scale. The output is a data frame with the predicted values x and y coordinates.

It can be easily added to a ggplot:

v1 <- 1:10
v2 <- exp(-v1)

ggplot() +
  geom_point(aes(v1, v2)) +
  geom_line(aes(x, y), data = log_line(v1, v2)) +
  coord_trans(y = "log")