R ggplot geom_tile неравномерный вертикальный интервал для дат

#r #ggplot2

#r #ggplot2

Вопрос:

 set.seed(1990)

ID <- rep(LETTERS,each = 12)
n <- rep(round(runif(12,1,10)), 26)
datetime <- rep(seq(as.POSIXct("2020-01-01"), as.POSIXct("2020-12-01"), by="month"), 26)
datetime <- lubridate::date(datetime)
dataset <- tibble(ID, datetime, n)

ggplot(dataset 
       ,
       aes(x=datetime,y= reorder(ID, n),fill=n)) 
  geom_tile(color = 'gray')  
  scale_x_date(expand = c(0,0),breaks = seq(as.Date("2014-07-01"), as.Date("2020-12-01"), by = "1 month"), date_labels = "%Y %b", name = 'Monthly') 

 

введите описание изображения здесь

Похоже, что интервал определяется продолжительностью дней для определенного месяца, что в данном контексте не очень полезно.

Временное решение, которое я нашел, заключается в преобразовании дат в коэффициент, но все равно оно кажется не самым лучшим, потому что горизонтальные промежутки также неравномерны.

 dataset$datetime <- factor(dataset$datetime)

ggplot(dataset 
       ,
       aes(x=datetime,y= reorder(ID, n),fill=n)) 
  geom_tile(color = 'gray')
 

введите описание изображения здесь

Но тогда я потеряю возможность использовать scale_x_date() для целей маркировки

 > ggplot(dataset 
         ,
         aes(x=datetime,y= reorder(ID, n),fill=n)) 
    geom_tile(color = 'gray')  
    scale_x_date(expand = c(0,0),breaks = seq(as.Date("2014-07-01"), as.Date("2020-12-01"), by = "1 month"), date_labels = "%Y %b", name = 'Monthly') 
Error: Invalid input: date_trans works with objects of class Date only
 

Чего я надеюсь достичь, так это идеального квадрата с равным расстоянием между всеми плитками, как показано ниже.
введите описание изображения здесь

Ответ №1:

Это немного взлом, но как насчет изменения даты на коэффициент в aes() вызове с zoo::as.yearmon(datetime) помощью . Затем вы можете использовать coord_equal() :

 library(zoo)
ggplot(dataset, aes(y = as.factor(zoo::as.yearmon(datetime)),
                    x = reorder(ID, n), fill=n))  
  geom_tile(color = 'gray')   labs(x = "Factor", y = "Date")  
  coord_equal() 
 

введите описание изображения здесь

Если вам нужно больше управления форматом, добавьте вызов format :

 ggplot(dataset ,aes(y = reorder(as.factor(format(zoo::as.yearmon(datetime),"%Y %b")),
                                zoo::as.yearmon(datetime)),
                    x = reorder(ID, n), fill = n))  
  geom_tile(color = 'gray')   labs(x = "Factor", y = "Date")  
  coord_equal() 
 

введите описание изображения здесь

Комментарии:

1. Потрясающе, сильно упростил мой код, и теперь легче понять, что происходит сейчас

2. Действительно, это работает, но только тогда, когда мы удаляем использование scale_x_date()