Hey everyone I am trying to show the intersection of a geom_line on a logarithmic x axis. However, I always miss the geom line. Here's what I do:
library(data.table)
library(ggplot2)
x <- c(0.1, 0.2)
y <- c(0.2, 0.4)
dt <- data.table(x = x,
y = y)
dt_lm <- lm(y ~ x, data = dt)
dt_slope <- summary(dt_lm)$coefficients[2, 1]
dt_inter <- summary(dt_lm)$coefficients[1, 1]
dt_x <- (0.3 - dt_inter) / dt_slope
ggplot(dt, aes(x, y)) +
geom_line() +
geom_segment(aes(x = 0,
xend = dt_x,
y = 0.3,
yend = 0.3),
color="red") +
geom_segment(aes(x = dt_x,
xend = dt_x,
y = 0,
yend = 0.3),
color="red") +
scale_x_continuous(trans = "log2")
I guess I have to take the log2
into account at the lm
, since without trans = "log2"
everything looks fine. However, I fail here :D
The problem is that geom_line
is simply drawing a straight line segment between the two points defined in dt
. With a log transform on the x axis, this "straight" line should actually be a curve, but an axis transformation will not convert a straight line segment between two points to a curve. To do this, you would need to get the correct x and y co-ordinates at all the points along the line and plot these.
There are a couple of ways to do that. You could get the curve to intersect at the correct point by interpolating many points along the line. This will allow geom_line
to draw hundreds of little line segments between the newly created co-ordinates, giving the visual effect of a smooth curve:
ggplot(as.data.frame(approx(dt$x, dt$y, n = 1000)), aes(x, y)) +
geom_line() +
geom_segment(aes(x = 0, xend = dt_x, y = 0.3, yend = 0.3), color = "red") +
geom_segment(aes(x = dt_x, xend = dt_x, y = 0, yend = 0.3), color = "red") +
scale_x_continuous(trans = "log2")
Perhaps a better approach is to get ggplot to do this for you. Although an axis transformation will not change a straight line to a curve, a coordinate transform will. For this, you need to use coord_trans
instead of applying your transformation via scale_x_continuous
ggplot(dt, aes(x, y)) +
geom_line() +
geom_segment(aes(x = 0.1, xend = dt_x, y = 0.3, yend = 0.3), color = "red") +
geom_segment(aes(x = dt_x, xend = dt_x, y = 0, yend = 0.3), color = "red") +
coord_trans(x = "log2", xlim = c(0.1, 0.2))
Note that this gives you the transformed x axis "for free", and has much nicer breaks that emphasize the log scale of the axis.