Question

Ploting weekly data with base::plot with unique and evenly spaced labels

I am trying to create a simple scatter plot, so weeks on the x-axis and "cases" on the y with each indicated by a dot and note I can only use base R's plot(), no ggplot.

I have data with 156 weeks (about 3 years), the weeks are anchored to March 19th 2020 date (going 7 days back and forward to create every week interval). Because of this many weeks start in the same month or include the boundary of two different months within their interval.

I'm trying to get only the 36 month-years on the x-axis labels, but it seems like there's no way to decouple the 156 data points (which I keep track of using the week start day) from the x-axis labels, so I either end up with repeat month-years or unevenly spaced tick marks. Is there any way to do this using basic R's plot() function? I cannot use ggplot. I think maybe what I need is some sort of base plot() version of ggplot's scale_x_date()?

I've tried converting the text dates to actual Date format with as.Date and then plotting that directly, but that still results in repeat month on the x-axis label...

Here's a toy example, trying to graph weeks x cases, but want the labels to be month-years rather than weeks:

Lines <- "Week_Interval        Cases     Week_Start
19-01-03-19-01-09   696537   2019-01-03
19-01-03-19-01-09   718748   2019-01-10
19-01-17-19-01-23   799355   2019-01-17
19-01-24-19-01-30   805800  2019-01-24
19-01-31-19-02-06   701262  2019-01-31
19-02-07-19-02-13   531579  2019-02-07
19-02-14-19-02-20   690068  2019-02-14
19-02-21-19-02-27   756947  2019-02-21
19-02-28-19-03-06   718757  2019-02-28
 9-03-07-19-03-13  701768    2019-03-07
19-03-14-19-03-20  820113   2019-03-14
19-03-21-19-03-27  645259   2019-03-21"


exampledata <- read.table(textConnection(Lines), header = TRUE)

exampledata$Date <- as.Date(exampledata$Week_Start)

# Plot outcome variable versus time
plot(exampledata$Date,exampledata$Cases,
main="Weeks by Cases",
ylab="Cases",
ylim=c(500000,900000),
xlab="",
las=2,
col="red",
xaxt="n")

# Add x-axis year labels
axis(1, exampledata$Date, format(exampledata$Date, "%b, %Y"))

# Add in the points for the figure
points(exampledata$Date,exampledata$Cases,
col="red",
pch=20)
 2  45  2
1 Jan 1970

Solution

 1

You can subset the dates on the non-duplicated 1st to 7th substring.

> plot(exampledata$Date, exampledata$Cases, main="Weeks by Cases", ylab="Cases",
+      ylim=c(500000, 900000), xlab="", las=2, col="red", xaxt="n", pch=20)
> ats <- exampledata$Date[!duplicated(substr(exampledata$Date, 1, 7))]
> axis(1, at=ats, labels=strftime(ats, '%b %Y'))

enter image description here

2024-07-25
jay.sf

Solution

 1

We can use seq.Date and axis.Date:

plot(exampledata$Date, exampledata$Cases,
     main="Weeks by Cases",
     ylab="Cases",
     ylim=c(500000,900000),
     xlab="",
     las=2,
     col="red",
     xaxt="n")

axis.Date(1, at = seq.Date(min(exampledata$Date), 
                           max(exampledata$Date), 
                           by = "month"), 
          format = "%b, %Y")

Created on 2024-07-25 with reprex v2.0.2

2024-07-25
M--