I'm trying to replicate the spiral example for geom_textpath() shown at the top here: https://allancameron.github.io/geomtextpath/
My y-axis is numeric, so that part works out fine, but my x-axis is a scale_x_datetime(), and I can't multiply datetimes by sin() values for the x variable.
Any ideas?
# install.packages("remotes")
remotes::install_github("AllanCameron/geomtextpath")
library(ggplot2)
library(geomtextpath)
t <- seq(5, -1, length.out = 1000) * pi
spiral <- data.frame(x = sin(t) * 1:1000,
y = cos(t) * 1:1000,
text = paste("Like a circle in a spiral,",
"like a wheel within a wheel,",
"never ending or beginning,",
"on an ever spinning reel")
)
ggplot(spiral, aes(x, y, label = text)) +
geom_textpath(size = 7, vjust = 2, text_only = TRUE) +
coord_equal(xlim = c(-1500, 1500), ylim = c(-1500, 1500))
Internally, POSIXct
is just numeric
with a class:
dput(Sys.time())
# structure(1745060382.54419, class = c("POSIXct", "POSIXt"))
So while sin(Sys.time())
isn't going to work, we can rescale the numeric x
axis to the appropriate range of numeric times, and then convert the class to POSIXt
.
We can use scales::rescale
but frankly the arithmetic is simple enough it can be done manually if desired. Since rescale
doesn't know about POSIXt
values, we can convert to numeric
, rescale, and then re-class back.
otherdat <- data.frame(y = seq(-1000, 1000, length.out = 11)) |>
transform(tm = Sys.time() + y)
spiral <- spiral |>
transform(tm = scales::rescale(x, from = range(x), to = as.numeric(range(otherdat$tm)))) |>
transform(tm = `class<-`(tm, class(otherdat$tm)))
ggplot(otherdat, aes(tm, y)) +
geom_point() +
geom_textpath(
data = spiral, aes(tm, y, label = text),
size = 7, vjust = 2, text_only = TRUE
) +
coord_equal(xlim = range(otherdat$tm) + c(-500, 500),
ylim = c(-1500, 1500))
Note that the xlim=
provides a time range instead of a numeric range. In this case, we're managing the POSIXt
values (seconds) to have the same range as the non-time y
-axis, over to you for your real use-case.