Description
posting here in the hopes of getting developer advice:
TL;DR:
vctrs
-objects implemented as list-type vectors fail ggplot2
's type checking for (continuous) scales, because scales are determined in train_position
before stats
are applied, and our vctrs
- objects are only converted to x-y-tuples by the specific Stat
we implement for our vctrs
-class.
we are uncertain what a feasible and sensible strategy is:
- go the whole
sf
route and implement entire custom coordinate systems etc (seems like it might be overkill in our case) - just implement new primary scale types specifically for our
vctrs
-objects (how?) - something else entirely?
we would appreciate any guidance or pointers to existing implementations solving similar issues.
more details:
Our package tf
defines a vctrs
-class tf
for vectors of functions --basically: lists of 2-column matrices containing
We were able to define a custom StatTf
and some custom geom
s based on it (e.g. geom-spaghetti) to enable quick plots like this:
> library(tidyfun)
> library(ggplot2)
> d <- data.frame(
+ x = tf_rgp(3), #3 random functions
+ f = factor(c(1,1,2))
+ )
> ggplot(d) + geom_spaghetti(aes(y = x, col = f))
This works for many different kinds of geom
s and facetting etc etc but breaks down currently as soon as we try to use for example scale
-transformations, see also tidyfun/tidyfun#135:
> ggplot(d) + geom_spaghetti(aes(y = x, col = f)) + scale_y_reverse()
Error in `as.character()`:
! Can't convert `x` <tfd_reg> to <character>.
Run `rlang::last_trace()` to see where the error occurred.
> rlang::last_trace()
<error/vctrs_error_cast>
Error in `as.character()`:
! Can't convert `x` <tfd_reg> to <character>.
---
Backtrace:
▆
1. ├─base (local) `<fn>`(x)
2. ├─ggplot2:::print.ggplot(x)
3. │ ├─ggplot2::ggplot_build(x)
4. │ └─ggplot2:::ggplot_build.ggplot(x)
5. │ └─layout$train_position(data, scale_x(), scale_y())
6. │ └─ggplot2 (local) train_position(..., self = self)
7. │ └─self$facet$train_scales(...)
8. │ └─ggplot2 (local) train_scales(...)
9. │ └─ggplot2:::scale_apply(layer_data, y_vars, "train", SCALE_Y, y_scales)
[...]