Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x_scale_datetime: timezone ignored when limits given #3440

Closed
phmarek opened this issue Jul 13, 2019 · 7 comments
Closed

x_scale_datetime: timezone ignored when limits given #3440

phmarek opened this issue Jul 13, 2019 · 7 comments
Labels
feature a feature request or enhancement scales 🐍

Comments

@phmarek
Copy link

phmarek commented Jul 13, 2019

I've got a plot that uses x_scale_datetime.

When using the whole data set, the x-axis has correct labels; but when I specify "limits" to restrict to a subset of the data, the tics get labelled as with a timezone "UTC".

@paleolimbot
Copy link
Member

I think you need your limits to be in the same timezone as your data! lubrdiate::with_tz() and/or lubridate::force_tz() may be able to help.

library(ggplot2)

df <- data.frame(
  x = lubridate::now(tzone = "America/Halifax") + lubridate::dhours(0:10),
  y = 0:10
)

limits <- lubridate::now(tzone = "America/Halifax") + lubridate::dhours(c(0.5, 9.5))

p <- ggplot(df, aes(x, y)) + geom_point()

p

p + scale_x_datetime(limits = limits)
#> Warning: Removed 2 rows containing missing values (geom_point).

Created on 2019-07-14 by the reprex package (v0.2.1)

@phmarek
Copy link
Author

phmarek commented Jul 15, 2019

Here's an example.

In reality I'm using read.table() to get data, but the column has the same ISO format I'm using here... and the limits are also given in ISO.

Furthermore, the timestamp values are correct (verified the unix timestamp versions).

require(ggplot2)
require(ggthemes)
library("parsedate")

dat <- data.frame( ts= c( 
						 parse_iso_8601("2019-07-12T08:00:00+02:00"),
						 parse_iso_8601("2019-07-12T12:00:00+02:00"),
						 parse_iso_8601("2019-07-12T16:00:00+02:00")
										),
				  val = c(1,3,2))

ggplot( dat, aes(x = ts, y = val) )+
scale_x_datetime( name = "Zeit",
				 timezone="CEST",
				 date_label = "%H:%M",
				 limits= c( parse_iso_8601("2019-07-12T08:00:00+02:00"), parse_iso_8601("2019-07-12T11:15:00+02:00"))
				 )+
geom_line()

If you comment the limits specification, you get a picture. When it's included, the x-axis labels become wrong (start at "06:00") and no line is visible. When the upper limits is set to 13:15, the line is drawn again, but starting from 06:00.
date_label and timezone are from googling the problem; they didn't help.

@phmarek
Copy link
Author

phmarek commented Jul 15, 2019

Update: With timezone="Europe/Vienna" the x-axis-labels are correct. Seems that this is a combination that I didn't yet try.
Still, I can't explain why these data and limits wouldn't be specific enough...

Sys.timezone() gives me ":/etc/localtime" (Debian amd64), is that the reason I need to explicitly set timezone? But why does it work without limits then?

Thanks a lot!

@paleolimbot
Copy link
Member

paleolimbot commented Jul 15, 2019

Parsing an ISO8601 date will give you the correct moment in time, but R has no way to know that UTC+2:00 is "Europe/Vienna" (it could well be an adjacent timezone on daylight savings). I highly suggest using lubridate::with_tz() on both your limits and data to make sure they are in the same timezone.

@phmarek
Copy link
Author

phmarek commented Jul 16, 2019

Well, sorry, I'm not sure I understand.

For the axis labels it doesn't matter _which +02:00 timezone I'm - the important information is to have the right offset for the given timestamps.

So, my first question is if ggplot2 sees "the timestamp data is +02:00, the limits are +02:00, timestamps enclose the limits" why isn't the timezone taken into account?
If the limits only give me some points in time (and the timezone is lost!), that should only restrict the data displayed, but not the formatting, IMO.

BTW, looking at scale_x_datetime documentation, I get timezone: The timezone to use for display on the axes. The default (‘NULL’) uses the timezone encoded in the data. - but my data has +02:00 too...

So thanks a lot for your help - but I still don't understand why I have to repeat my system timezone when specifying limits (but not without them)... I still believe this to be a bug.

Thanks a lot!

@paleolimbot
Copy link
Member

I see your point...there is no theoretical reason why limits for a datetime scale have to be in the same timezone as the data (although a quite reasonable workaround is to make sure that this is the case).

@paleolimbot paleolimbot reopened this Jul 22, 2019
@paleolimbot paleolimbot added feature a feature request or enhancement scales 🐍 labels Jul 22, 2019
@teunbrand
Copy link
Collaborator

The timezone information is dropped during conversion, so there is no way for ggplot2 to know what timezone the data had originally.

Note the 08:00+02:00 becomes 06:00+UTC:

parsedate::parse_iso_8601("2019-07-12T08:00:00+02:00")
#> [1] "2019-07-12 06:00:00 UTC"

Created on 2024-08-28 with reprex v2.1.1

You could use lubridate::as_datetime(..., tz = "Europe/Vienna") to parse the date instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature request or enhancement scales 🐍
Projects
None yet
Development

No branches or pull requests

3 participants