Search code examples
rdateplottimeserieschart

R plot multiple observations per day


I have been struggling to create a time series dot plot (not a boxplot) that will accommodate the stylized data shown below which has multiple datapoints per day.

The data is sparsely populated and will be missing data for many days over the date range, however some days might have hundreds of datapoints within a narrow range of values. The x axis must span the entire date range and include pretty tick marks even for days that do not have any data.

I would be nice if x axis labels vertically positioned and the y axis labels horizontally positioned.

I've been in help and googled around and spent hours with ggplot2, ts(), axis() settings etc. without success. The x axis is especially problematic.

It seems like this should be so easy but I'm an R noob.

dt,     RotMarks  
2017-01-01,    1  
2017-01-01,    3  
2017-03-10,    2  
2017-03-10,    4  
2017-03-10,    6  
2017-06-15,    10  
2017-06-15,    15  
2017-09-20,    1  
2017-10-31,    12  
2017-10-31,    12  
2017-10-31,    12  
2017-10-31,    12  
2017-10-31,    12  
2017-10-31,    12  
2017-10-31,    12  
2017-10-31,    4  
2017-10-31,    4  
2017-10-31,    4  
2017-10-31,    4  
2017-10-31,    1  
2017-10-31,    1  
2017-10-31,    1  
2017-10-31,    1  
2017-12-31,    1  
2017-12-31,    1  
2017-12-31,    1  

Solution

  • A solution using the package. I don't think to label the x-axis with each date is a good idea because it would be too crowded. You can see that the example uses date breaks as "2 weeks", and it has already been a little bit crowded. date_labels = "%Y-%m-%d" is to specify the date format. axis.text.x = element_text(angle = 90, hjust = 1) is to vertically position the x labels.

    library(tidyverse)
    
    # Expand the data frame to full sequence of dates    
    dat2 <- dat %>%
      mutate(dt = as.Date(dt)) %>%
      complete(dt = full_seq(dt, period = 1))
    
    ggplot(dat2, aes(x = dt, y = RotMarks)) +
      geom_point() +
      scale_x_date(name = "Date", 
                   date_labels = "%Y-%m-%d", 
                   date_breaks = "2 weeks") +
      theme(axis.text.x = element_text(angle = 90, hjust = 1))
    

    enter image description here

    DATA

    dat <- read.csv(text = "dt,     RotMarks  
    2017-01-01,    1  
                     2017-01-01,    3  
                     2017-03-10,    2  
                     2017-03-10,    4  
                     2017-03-10,    6  
                     2017-06-15,    10  
                     2017-06-15,    15  
                     2017-09-20,    1  
                     2017-10-31,    12  
                     2017-10-31,    12  
                     2017-10-31,    12  
                     2017-10-31,    12  
                     2017-10-31,    12  
                     2017-10-31,    12  
                     2017-10-31,    12  
                     2017-10-31,    4  
                     2017-10-31,    4  
                     2017-10-31,    4  
                     2017-10-31,    4  
                     2017-10-31,    1  
                     2017-10-31,    1  
                     2017-10-31,    1  
                     2017-10-31,    1  
                     2017-12-31,    1  
                     2017-12-31,    1  
                     2017-12-31,    1",
                     header = TRUE, stringsAsFactors = FALSE)