0

I ran into a problem with the datetime x-axis in R. I would like to have the breaks to the 1st of every month. However, it only works until March - then, instead of showing 1st April, the plot shows "31st March" and only continues to show the last day of month (see photo below) I've been searching for a while now, and tried different approaches (xlim, setting a sequence of breaks etc., using the date column with scale_x_date instead of the POSIX.ct. Nothing has worked.

I would like to keep the POSIXct format and the limits, as I am plotting different plots below each other (including data that requires POSIXct format).

Any help would be greatly appreciated. Best regards, tofeta

Image showing the plot result and the problem

Update of Code and Data

Code:

## Plot d
d$Date <- as.Date(d$Date, format="%d.%m.%Y")
d$timestep <- as.POSIXct(paste(d$Date, "00:00"), format="%Y-%m-%d %H:%S")

ggplot()+geom_line(aes(x=d$timestep, y=d$Mean_Temp),
                    (scale_x_datetime(labels = date_format("%d-%b"),
                    limits = c(as.POSIXct("2016-01-01"),
                               as.POSIXct("2016-05-31")),expand = c(0,0), 
                              date_breaks="months"))

 ## Plot d1
 d1$timestep <- (as.POSIXct(d1$timestep, format="%m.%d.%y %H:%M:%S"))

ggplot(data=d1, aes(x=d1$timestep, y=d1$q))+ 
  geom_line()+
  scale_x_datetime(labels = date_format("%d-%b"),
                   limits = c(as.POSIXct("2016-01-01"),
                              as.POSIXct("2016-05-31")),
                   expand = c(0,0), 
                   date_breaks="months")

Here is my data (I could not reproduce this error with a minimal dataset, so here is a subset:)

# d1

structure(list(Date = structure(c(1L, 6L, 11L, 16L, 21L, 26L, 
31L, 36L, 41L, 46L, 51L, 56L, 61L, 66L, 71L, 76L, 81L, 86L, 91L, 
96L, 101L, 106L, 111L, 116L, 121L, 126L, 131L, 136L, 141L, 146L, 
150L, 2L, 7L, 12L, 17L, 22L, 27L, 32L, 37L, 42L, 47L, 52L, 57L, 
62L, 67L, 72L, 77L, 82L, 87L, 92L, 97L, 102L, 107L, 112L, 117L, 
122L, 127L, 132L, 137L, 142L, 3L, 8L, 13L, 18L, 23L, 28L, 33L, 
38L, 43L, 48L, 53L, 58L, 63L, 68L, 73L, 78L, 83L, 88L, 93L, 98L, 
103L, 108L, 113L, 118L, 123L, 128L, 133L, 138L, 143L, 147L, 151L, 
4L, 9L, 14L, 19L, 24L, 29L, 34L, 39L, 44L, 49L, 54L, 59L, 64L, 
69L, 74L, 79L, 84L, 89L, 94L, 99L, 104L, 109L, 114L, 119L, 124L, 
129L, 134L, 139L, 144L, 148L, 5L, 10L, 15L, 20L, 25L, 30L, 35L, 
40L, 45L, 50L, 55L, 60L, 65L, 70L, 75L, 80L, 85L, 90L, 95L, 100L, 
105L, 110L, 115L, 120L, 125L, 130L, 135L, 140L, 145L, 149L, 152L
), .Label = c("01.01.2016", "01.02.2016", "01.03.2016", "01.04.2016", 
"01.05.2016", "02.01.2016", "02.02.2016", "02.03.2016", "02.04.2016", 
"02.05.2016", "03.01.2016", "03.02.2016", "03.03.2016", "03.04.2016", 
"03.05.2016", "04.01.2016", "04.02.2016", "04.03.2016", "04.04.2016", 
"04.05.2016", "05.01.2016", "05.02.2016", "05.03.2016", "05.04.2016", 
"05.05.2016", "06.01.2016", "06.02.2016", "06.03.2016", "06.04.2016", 
"06.05.2016", "07.01.2016", "07.02.2016", "07.03.2016", "07.04.2016", 
"07.05.2016", "08.01.2016", "08.02.2016", "08.03.2016", "08.04.2016", 
"08.05.2016", "09.01.2016", "09.02.2016", "09.03.2016", "09.04.2016", 
"09.05.2016", "10.01.2016", "10.02.2016", "10.03.2016", "10.04.2016", 
"10.05.2016", "11.01.2016", "11.02.2016", "11.03.2016", "11.04.2016", 
"11.05.2016", "12.01.2016", "12.02.2016", "12.03.2016", "12.04.2016", 
"12.05.2016", "13.01.2016", "13.02.2016", "13.03.2016", "13.04.2016", 
"13.05.2016", "14.01.2016", "14.02.2016", "14.03.2016", "14.04.2016", 
"14.05.2016", "15.01.2016", "15.02.2016", "15.03.2016", "15.04.2016", 
"15.05.2016", "16.01.2016", "16.02.2016", "16.03.2016", "16.04.2016", 
"16.05.2016", "17.01.2016", "17.02.2016", "17.03.2016", "17.04.2016", 
"17.05.2016", "18.01.2016", "18.02.2016", "18.03.2016", "18.04.2016", 
"18.05.2016", "19.01.2016", "19.02.2016", "19.03.2016", "19.04.2016", 
"19.05.2016", "20.01.2016", "20.02.2016", "20.03.2016", "20.04.2016", 
"20.05.2016", "21.01.2016", "21.02.2016", "21.03.2016", "21.04.2016", 
"21.05.2016", "22.01.2016", "22.02.2016", "22.03.2016", "22.04.2016", 
"22.05.2016", "23.01.2016", "23.02.2016", "23.03.2016", "23.04.2016", 
"23.05.2016", "24.01.2016", "24.02.2016", "24.03.2016", "24.04.2016", 
"24.05.2016", "25.01.2016", "25.02.2016", "25.03.2016", "25.04.2016", 
"25.05.2016", "26.01.2016", "26.02.2016", "26.03.2016", "26.04.2016", 
"26.05.2016", "27.01.2016", "27.02.2016", "27.03.2016", "27.04.2016", 
"27.05.2016", "28.01.2016", "28.02.2016", "28.03.2016", "28.04.2016", 
"28.05.2016", "29.01.2016", "29.02.2016", "29.03.2016", "29.04.2016", 
"29.05.2016", "30.01.2016", "30.03.2016", "30.04.2016", "30.05.2016", 
"31.01.2016", "31.03.2016", "31.05.2016"), class = "factor"), 
Mean_Temp = c(-12.9, -10.4, -10.2, -13.7, -9.4, -11.5, -11.9, 
-10.4, -14.3, -20.5, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, -19.7, -17.6, -15.3, -13, -13.9, 
-14.3, -15.8, -21.5, -27.4, -30.6, -28.6, -24.4, -28.4, -23.1, 
-20, -18.7, NA, -13.8, -19.8, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, -16.2, -16.3, -11.5, -10.7, NA, -20.2, -20.2, -17.9, 
-21.1, -23.9, -26.2, -19.8, -25.1, -28.4, -24.2, -18.7, -18.4, 
-14.4, -16, -18.1, -21.1, -22.1, -23.4, -23.5, -23.8, -22.3, 
-22.2, -21.2, -18.8, -12.6, -15.1, -14.8, -13.7, NA, -18.3, 
-21.5, -23.8, -22.7, -25.1, -21.4, -18.7, -21.4, -16.4, -16.6, 
-16.1, -17.9, -15.3, -13.9, -16.3, -17.4, -12.4, -15.7, -18.2, 
-15.1, -7.2, -6, -10.5, -12.1, -13, -12.6, -10, -6.1, -3.4, 
-4.7, -2.5, -3.5, -1.3, -3.8, -3.8, -0.5, -1.4, -3.5, -4.1, 
-3.6, -1.6, -1, -1.4, -2.2, NA, 4.4, 3.5, 2.5, -0.7, -0.6, 
0.3, -1.7, 0.5, 3.4, 3.4, 1, NA, -0.1, 1.5, 1.7, NA, -0.3, 
-0.8, 1.8, 1.5)), .Names = c("Date", "Mean_Temp"), class = "data.frame", 
row.names = c(NA, 
-152L))

#d1

structure(list(timestep = structure(1:58, .Label = c("05.14.16 09:00:00", 
"05.14.16 09:30:00", "05.14.16 10:00:00", "05.14.16 10:30:00", 
"05.14.16 11:00:00", "05.14.16 11:30:00", "05.14.16 12:00:00", 
"05.14.16 12:30:00", "05.14.16 13:00:00", "05.14.16 13:30:00", 
"05.14.16 14:00:00", "05.14.16 14:30:00", "05.14.16 15:00:00", 
"05.14.16 15:30:00", "05.14.16 16:00:00", "05.14.16 16:30:00", 
"05.14.16 17:00:00", "05.14.16 17:30:00", "05.14.16 18:00:00", 
"05.14.16 18:30:00", "05.14.16 19:00:00", "05.14.16 19:30:00", 
"05.14.16 20:00:00", "05.14.16 20:30:00", "05.14.16 21:00:00", 
"05.14.16 21:30:00", "05.14.16 22:00:00", "05.14.16 22:30:00", 
"05.14.16 23:00:00", "05.14.16 23:30:00", "05.15.16 00:00:00", 
"05.15.16 00:30:00", "05.15.16 01:00:00", "05.15.16 01:30:00", 
"05.15.16 02:00:00", "05.15.16 02:30:00", "05.15.16 03:00:00", 
"05.15.16 03:30:00", "05.15.16 04:00:00", "05.15.16 04:30:00", 
"05.15.16 05:00:00", "05.15.16 05:30:00", "05.15.16 06:00:00", 
"05.15.16 06:30:00", "05.15.16 07:00:00", "05.15.16 07:30:00", 
"05.15.16 08:00:00", "05.15.16 08:30:00", "05.15.16 09:00:00", 
"05.15.16 09:30:00", "05.15.16 10:00:00", "05.15.16 10:30:00", 
"05.15.16 11:00:00", "05.15.16 11:30:00", "05.15.16 12:00:00", 
"05.15.16 12:30:00", "05.15.16 13:00:00", "05.15.16 13:30:00"
), class = "factor"), q = c(0.37726, 0.37618, 0.37943, 0.37943, 
0.38161, 0.38161, 0.37943, 0.37726, 0.37943, 0.37943, 0.37943, 
0.37835, 0.37943, 0.38161, 0.38598, 0.38052, 0.38052, 0.38379, 
0.37726, 0.37943, 0.37835, 0.37618, 0.37402, 0.37618, 0.37835, 
0.37726, 0.37835, 0.37943, 0.37618, 0.3751, 0.37294, 0.37294, 
0.37294, 0.36758, 0.36544, 0.36544, 0.36544, 0.36225, 0.36013, 
0.36225, 0.36013, 0.36225, 0.36119, 0.35907, 0.35907, 0.35696, 
0.35801, 0.36119, 0.35907, 0.36225, 0.36119, 0.35907, 0.35696, 
0.35696, 0.35696, 0.35696, 0.35801, 0.35485)), .Names = c("timestep", 
"q"), class = "data.frame", row.names = c(NA, -58L))

Many thanks.

tofeta
  • 11
  • 1
  • 3
  • Change limits to `limits = c(as.POSIXct("2016-01-01"), as.POSIXct("2017-01-01"))`? – Mako212 Feb 27 '18 at 22:25
  • 1
    Otherwise please see [Creating a Great Reproducible Example in R](https://stackoverflow.com/a/5963610/4421870), and provide a sample of your source data so we can test solutions. – Mako212 Feb 27 '18 at 22:26
  • 1
    This works: `d <- data.frame(date = as.Date("2016-01-01") + 0:365, y = cumsum(rnorm(366)))`; `ggplot(d, aes(date, y)) + geom_line() + scale_x_date(date_breaks = "month")` – Henrik Feb 27 '18 at 22:38
  • Thank you. Please see my updated code and data. I would like to keep the POSIXct version, as I want to create another plot, which requires this format. – tofeta Feb 28 '18 at 18:25

2 Answers2

4

There's numerous odd things with your code. I don't think you need to set limits if you have daily data. You can set the labels with date_labels argument to scale_x_date, rather than labels. geom_line doesn't take a fill argument. Use "1 month" for the argument date_breaks, rather than "months". I'd also recommend looking at a style guide so it's easier to see what arguments belong to what functions in your code. Note also that I never managed to get this shifting error that you mentioned; this is why it's important to provide a reproducible example as commenters said.

library(tidyverse)
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
tbl <- tibble(
  day = seq.Date(ymd("2016-01-01"), ymd("2017-01-01"), by = 1)
) %>%
  mutate(temp = rnorm(nrow(.), mean = 0, sd = 15))

ggplot(tbl) +
  geom_line(aes(x = day, y = temp), color="#D55E00") +
  scale_x_date(date_breaks = "1 month", date_labels = "%d-%b")

Created on 2018-02-27 by the reprex package (v0.2.0).

Calum You
  • 14,687
  • 4
  • 23
  • 42
  • Thanks for this suggestion. Your sample code works fine for me - but the problem with my code still remains. I updated my code and data in my question above. I would like to use the same code on some other data, which requires the POSIXct format and only starts in May. This is why, keeping the limits would be good. – tofeta Feb 28 '18 at 18:28
0

I changed this part of the code:

 labels = date_format("%d-%b") 

to:

date_labels = "%d-%b"  

And that did the trick.

Maybe this helps somebody else who runs into a similar problem.

tofeta
  • 11
  • 1
  • 3