altair icon indicating copy to clipboard operation
altair copied to clipboard

Date x-axis is shifted by -1 day

Open topspinj opened this issue 3 years ago • 10 comments

I've been using Altair within Streamlit and have been enjoying it for the most part. However, I noticed that Altair behaves oddly when I create plots where the x-axis is a date field.

Screen Shot 2021-12-21 at 2 12 41 PM

the min date is Sept 1, 2021 but when I hover over the Altair chart, it says Aug 31, 2021 🤔

I haven't reproduced this in Jupyter notebooks yet but I do see this strange behaviour consistently in the context of Streamlit. Anyone else experience this issue?

topspinj avatar Dec 21 '21 19:12 topspinj

This is a timezone/date parsing issue in Javascript. You need your date strings to be fully-qualified ISO 8601 date strings, or Javascript will parse them as UTC rather than local time. If you use a pandas dataframe and ensure that your column is a datetime type, Altair will take care of the details for you. See e.g. https://github.com/vega/vega-lite/issues/6883 for details.

jakevdp avatar Dec 21 '21 19:12 jakevdp

Thanks for the swift response. I'm really glad you shared this issue with me because I wouldn't have found it otherwise. Do you think this is worth adding to the docs?

topspinj avatar Dec 21 '21 19:12 topspinj

Yeah, it might be worth adding this in a FAQ or a "gotchas" page.

jakevdp avatar Dec 21 '21 20:12 jakevdp

Here's a similar issue in the Altair repo: https://github.com/altair-viz/altair/issues/2077

jakevdp avatar Dec 21 '21 20:12 jakevdp

I tried casting the column to datetime and set utc=True. Still getting that weird -1 day behaviour in the plots.

pd.to_datetime(df["date"], utc=True)

Am I doing this right? I'm not familiar with ISO8601 strings so let me know if I'm doing this wrong.

topspinj avatar Dec 21 '21 20:12 topspinj

You probably don't want utc=True. If you do, then you should use UTC timeunits in your chart as well.

(also, just in case this is an area of confusion: pd.to_datetime does not do any in-place modification: you have to assign the result to something; e.g. df["date"] = pd.to_datetime(df["date"]))

jakevdp avatar Dec 21 '21 20:12 jakevdp

I encountered a similar off by one issue on SO the other day and I think that one was timezone related and will be fixed when this vegalite issue is closed https://github.com/vega/vega-lite/issues/7795

joelostblom avatar Dec 22 '21 07:12 joelostblom

Thanks for sharing this! looks like this PR is still waiting for reviewers. Unfortunately I don't have the context to review this particular PR but hopefully it gets shipped soon :shipit:

Any work-arounds that you've used in the meantime @joelostblom?

topspinj avatar Jan 19 '22 22:01 topspinj

I'm not sure on the top of my head, but you could try writing your dates as "2011-10-02T00:00:00" as Jake mentions here https://github.com/vega/vega-lite/issues/6883#issuecomment-696862778 (and maybe play with including time zone info or not) or setting the axis values explicitly as mentioned here https://github.com/altair-viz/altair/issues/2077

joelostblom avatar Jan 21 '22 01:01 joelostblom

@topspinj I just posted a possible workaround in this SO answer that you can try https://stackoverflow.com/a/71685940/2166823

joelostblom avatar Mar 31 '22 01:03 joelostblom

The corresponding Vega-Lite issues have now been merged and this appears fixed to me when trying with the SO example I linked above, so closing this. Please reopen with a spec that is not working in altair 5 if there are still issues.

joelostblom avatar Sep 21 '23 16:09 joelostblom