DavisVaughan / datea

Extended Date Classes
Other
1 stars 0 forks source link

ggplot2 scales #10

Open earowang opened 4 years ago

earowang commented 4 years ago

Hi Davis,

Regarding https://github.com/r-lib/vctrs/issues/1154

It used to work nicely with scales, when subclassing Date. Although we use different underlying representations between yearmonth and ymon, the axis issue remains the same. When the limit difference is small, the labels fall out of the plotting range.

library(datea)
scale_type.ymon <- function(x) c("ymon", "date", "continuous")

ymon_trans <- function() {
  scales::trans_new(
    "ymon",
    transform = function(x) {
      scales::date_trans()$transform(as.Date(x))
    },
    inverse = function(x) {
      as_ymon(scales::date_trans()$inverse(x))
    },
    breaks = function(x) {
      as_ymon(scales::breaks_pretty()(as.Date(x)))
    }
  )
}

scale_x_ymon <- function(...) {
  ggplot2::ggproto("ScaleContinuousYearmonth", ggplot2::scale_x_date(...),
                   trans = ymon_trans())
}

library(ggplot2)
library(tibble)
tibble(idx = ymon(year = 1970, month = 2:12), y = rnorm(11)) %>% 
  ggplot(aes(x = idx, y = y)) + 
  geom_line()

tibble(idx = ymon(year = 1980, month = 2:12), y = rnorm(11)) %>% 
  ggplot(aes(x = idx, y = y)) + 
  geom_line()

Created on 2020-06-19 by the reprex package (v0.3.0)

earowang commented 4 years ago

Actually, the graphical issue also applies to zoo::yearmon().

DavisVaughan commented 4 years ago

I'll be completely honest, I don't have much experience creating scales, but I'd guess that we'd have to create one for ymon anyways since it has a different granularity than Date, rather than just using Date's directly. I'm not really sure though

earowang commented 4 years ago

Granularity isn't the issue. pretty() handles Dates in monthly intervals very well. The ticks and labels in the plots above are perfect, except for "Jan" out of plot limits. This didn't occur to yearmonth when subclassing Date. However, when explicitly converting to Date, the issue pops out. "Jan" should be interpreted as NA, but it is somehow changed to 0 when building ggplot.

Anyway, that is my primary motivation for inheriting from Date, without creating my own scale_x_*().