如何使用 ggplot 正确绘制带日期的直方图?

How to properly plot a histogram with dates using ggplot?

我想创建一个以日期为 x 轴的交互式直方图。
我用过ggplot+ggplotly.

我读过我需要使用“text=as.character(mydates)”选项传递正确的信息,有时还使用“tooltips=mytext”。

这个技巧适用于其他类型的图,但直方图存在问题,我没有得到具有单个值的单个条,而是堆叠了许多子条。
我想原因是传递“text=as.character(fechas)”会产生许多值,而不仅仅是定义该栏的 class 值。

我该如何解决这个问题?
我尝试自己过滤数据,但我不知道如何使这些参数与直方图使用的参数匹配,例如每个柱的日期开始位置。

library(lubridate)
library(ggplot2)
library(ggplotly)

Ejemplo <- data.frame(fechas = dmy("1-1-20")+sample(1:100,100, replace=T),
            valores=runif(100))

dibujo <- ggplot(Ejemplo, aes(x=fechas, text=as.character(fechas))) +  
  theme_bw() +  geom_histogram(binwidth=7, fill="darkblue",color="black") +
  labs(x="Fecha", y="Nº casos") + 
  theme(axis.text.x=element_text(angle=60, hjust=1)) +
  scale_x_date(date_breaks = "weeks", date_labels = "%d-%m-%Y", 
  limits=c(dmy("1-1-20"), dmy("1-4-20"))) 

ggplotly(dibujo)
ggplotly(dibujo, tooltip = "text")

如您所见,条形不是常规的直方图条形,而是一些复杂的东西。
仅使用 ggplot 而不是 ggplotly 会显示相同的问题,但您不需要使用额外的“文本”参数。

目前,将 as.character(fechas) 提供给 aes() 内的 text = ... 参数将显示 distinct 日期的相对计数 个垃圾箱内。请注意,第一个条形的高度只是对 1 月 6 日和 1 月 13 日之间的日期总数的计数。

仔细阅读您的问题后,您似乎希望每个周间隔内的 最大 日期。换句话说,一个日期应该悬停在每个栏上。如果您偏向于将 ggplot 对象转换为 plotly 对象,那么我建议在将数据帧提供给 ggplot() 函数之前对其进行预处理。首先,按周分组。其次,按每周间隔拉出所需日期以显示为文本(即结束日期)。接下来,将这个新数据框提供给 ggplot(),但现在在 geom_col() 上分层。这将实现类似的输出,因为您按每周间隔分组。

library(dplyr)
library(lubridate)
library(ggplot2)
library(plotly)

set.seed(13)
Ejemplo <- data.frame(fechas = dmy("1-1-20") + sample(1:100, 100, replace = T),
                      valores = runif(100))

Ejemplo_stat <- Ejemplo %>%
  arrange(fechas) %>%
  filter(fechas >= ymd("2020-01-01"), fechas <= ymd("2020-04-01")) %>%  # specify the limits manually
  mutate(week = week(fechas)) %>%                                       # create a week variable
  group_by(week) %>%                                                    # group by week
  summarize(total_days = n(),                                           # total number of distinct days
            last_date = max(fechas))                                    # pull the maximum date within each weekly interval            

dibujo <- ggplot(Ejemplo_stat, aes(x = factor(week), y = total_days, text = as.character(last_date))) +
  geom_col(fill = "darkblue", color = "black") +
  labs(x = "Fecha", y = "Nº casos") + 
  theme_bw() + 
  theme(axis.text.x = element_text(angle = 60, hjust = 1)) +
  scale_x_discrete(label = function(x) paste("Week", x))

ggplotly(dibujo)                    # add more text (e.g., week id, total unique dates, and end date)    
ggplotly(dibujo, tooltip = "text")  # only the end date is revealed

根据要求,一旦您将鼠标悬停在每个条上,就会显示“结束日期”。请注意,值“2020-01-12”是而不是第二周的最后一天。这是在第二个每周间隔中观察到的最后日期

预处理方法的好处是您可以根据需要修改分组数据框。例如,您可以随意将日期范围限制为更小(或更大)的周子集,或者在一周中的不同日期(例如星期日)开始您的周。此外,如果您想要显示更多文本选项,您还可以在每个栏旁边显示 唯一日期的总数 ,甚至可以显示每周的日期范围。