如何使用 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”是而不是第二周的最后一天。这是在第二个每周间隔中观察到的最后日期。
预处理方法的好处是您可以根据需要修改分组数据框。例如,您可以随意将日期范围限制为更小(或更大)的周子集,或者在一周中的不同日期(例如星期日)开始您的周。此外,如果您想要显示更多文本选项,您还可以在每个栏旁边显示 唯一日期的总数 ,甚至可以显示每周的日期范围。
我想创建一个以日期为 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”是而不是第二周的最后一天。这是在第二个每周间隔中观察到的最后日期。
预处理方法的好处是您可以根据需要修改分组数据框。例如,您可以随意将日期范围限制为更小(或更大)的周子集,或者在一周中的不同日期(例如星期日)开始您的周。此外,如果您想要显示更多文本选项,您还可以在每个栏旁边显示 唯一日期的总数 ,甚至可以显示每周的日期范围。