0
votes

I would like to create an interactive histogram with dates on the x-axis.
I have used ggplot+ggplotly.

I've read I need to use to pass the proper information using the "text=as.character(mydates)" option and sometimes "tooltips=mytext".

This trick works for other kinds of plots but there is a problem with the histograms, instead of getting a single bar with a single value I get many sub-bars stacked.
I guess the reason is passing "text=as.character(fechas)" produces many values instead of just the class value defining that bar.

How can I solve this problem?
I have tried filtering myself the data but I don't know how to make this the parameters match the parameters used by the histogram, such as where the dates start for each bar.

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")

enter image description here

As you can see, the bars are not regular histogram bars but something complex.
Using just ggplot instead of ggplotly shows the same problem, though then you woulnd't need to use the extra "text" parameter.

1
What is the purpose of valores in your example?Thomas Bilach

1 Answers

1
votes

Presently, feeding as.character(fechas) to the text = ... argument inside of aes() will display the relative counts of distinct dates within each bin. Note the height of the first bar is simply a count of the total number of dates between 6th of January and the 13th of January.

After a thorough reading of your question, it appears you want the maximum date within each weekly interval. In other words, one date should hover over each bar. If you're partial to converting ggplot objects into plotly objects, then I would advise pre-processing the data frame before feeding it to the ggplot() function. First, group by week. Second, pull the desired date by each weekly interval to show as text (i.e., end date). Next, feed this new data frame to ggplot(), but now layer on geom_col(). This will achieve similar output since you're grouping by weekly intervals.

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

plotly end date

The "end date" is displayed once you hover over each bar, as requested. Note, the value "2020-01-12" is not the last day of the second week. It is the last date observed in the second weekly interval.

The benefit of the preprocessing approach is your ability to modify your grouped data frame, as needed. For example, feel free to limit the date range to a smaller (or larger) subset of weeks, or start your weeks on a different day of the week (e.g., Sunday). Furthermore, if you want more textual options to display, you could also display your total number of unique dates next to each bar, or even display the date ranges for each week.