【问题标题】:How to properly plot a histogram with dates using ggplot?如何使用ggplot正确绘制带有日期的直方图?
【发布时间】:2021-02-27 13:28:55
【问题描述】:

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

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

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

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

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 会显示相同的问题,但您不需要使用额外的“文本”参数。

【问题讨论】:

  • 你的例子中valores的目的是什么?

标签: r data-visualization histogram ggplot2


【解决方案1】:

目前,将as.character(fechas) 提供给aes() 内的text = ... 参数将显示不同 日期 每个bin 的相对计数。请注意,第一个条的高度只是 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”不是第二周的最后一天。这是第二个每周间隔内观察到的最后日期

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

【讨论】:

  • 您希望它在您将鼠标悬停在垃圾箱的每个部分上时显示所有日期吗?如果是这样,那么为什么不抑制分隔每个 bin 内的相对计数的黑线呢?
  • 我希望它在每个 bin 中只显示一个日期,即间隔的结束日期。
  • 您是指每箱一个日期吗?例如,将鼠标悬停在第一个栏上应返回“2020-01-12”或每个周 bin 内的最后日期?
  • 试试:as.character(ceiling_date(last_date - 7, unit = c("week"), week_start = 0))。这适用于我的代码。它将为您划定周数,为您提供每个周间隔的最后一天(即 5 日、12 日、19 日等)。请注意,我必须将日期变量调整为从月初开始。虽然它看起来效率较低,但它绕过了geom_bar() 的默认行为。
  • 将条形左移:geom_col(..., position = position_nudge(x = -0.5))。这适用于任意数量的时间单位。
猜你喜欢
  • 2023-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 2015-03-05
  • 2014-08-20
  • 2014-06-12
  • 1970-01-01
相关资源
最近更新 更多