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

plot_date() ignores timezone in matplotlib version 2.0.0 #8072

Closed
robinloxley1 opened this issue Feb 14, 2017 · 23 comments · Fixed by #27850
Closed

plot_date() ignores timezone in matplotlib version 2.0.0 #8072

robinloxley1 opened this issue Feb 14, 2017 · 23 comments · Fixed by #27850
Assignees
Labels
keep Items to be ignored by the “Stale” Github Action topic: date handling topic: units and array ducktypes
Milestone

Comments

@robinloxley1
Copy link

Bug report

Bug summary

copy paste the code from #5575

import pytz
import matplotlib.pyplot as plt
from datetime import datetime
time_index = [pytz.timezone('Europe/Berlin').localize(datetime(year=2015, month=11, day=27, hour=x)) for x in range(4)]
plt.plot_date(time_index, [4]*4, tz='Europe/Berlin')
plt.plot_date(time_index, [3]*4, tz='UTC')

Actual outcome

  • The output gives no difference in xaxis, implying tz is not working.
@dstansby dstansby added this to the 2.0.1 (next bug fix release) milestone Feb 14, 2017
@dstansby
Copy link
Member

For reference, this works fine if the two plots are on different axes, which is all #6091 tests for. The problem happens if two plots with different timezones are done on the same axis.

@tacaswell tacaswell modified the milestones: 2.1 (next point release), 2.0.1 (next bug fix release) Feb 14, 2017
@tacaswell
Copy link
Member

What timezone would you expect the axes to be in if you pass in data with different timezones (which may be considered 'different units')?

@phobson phobson changed the title plot_date() ignores timezone AGAIN for matplotlib version 2.0.0 plot_date() ignores timezone in matplotlib version 2.0.0 Feb 14, 2017
@anntzer
Copy link
Contributor

anntzer commented Apr 15, 2017

It seems natural enough to convert everything to the axis' tz?

@tacaswell tacaswell modified the milestones: 2.1 (next point release), 2.2 (next next feature release) Sep 24, 2017
@jklymak jklymak modified the milestones: needs sorting, v3.0 Mar 24, 2018
@samarthwhistle
Copy link

Is there any confirmation on whether this is going to be fixed in v3.0?

@jklymak
Copy link
Member

jklymak commented Jul 24, 2018

I don't think there is a fix for this right now. OTOH, I suspect its not too hard to do. PR would be welcome...

@jklymak
Copy link
Member

jklymak commented Jul 24, 2018

Actually, I take that back. The problem is that axis.update_units only checks that the converter is appropriate for the data, not the actual units of the data. So the fix is to fix the units machinery, but thats under review.

@jklymak jklymak modified the milestones: v3.0, v3.1 Jul 24, 2018
@samarthwhistle
Copy link

Thanks for providing this information. Looking forward to the fix!

@jklymak
Copy link
Member

jklymak commented Jul 24, 2018

I agree that the documentation shouldn't claim that this works. Not sure how we indicate that a kwarg actually has no effect, but that we'd like it to someday...

I wouldn't expect this in the forseable future, as it gets at the root of our units handling, which is currently not set up to change units on the fly. Safest is to convert all your datetime objects to one timezone and then plot.

@jklymak jklymak modified the milestones: v3.1.0, v3.2.0 Feb 10, 2019
@timhoffm timhoffm modified the milestones: v3.2.0, v3.3.0 Aug 16, 2019
@QuLogic QuLogic modified the milestones: v3.3.0, v3.4.0 May 7, 2020
@QuLogic QuLogic modified the milestones: v3.4.0, v3.5.0 Jan 27, 2021
@QuLogic QuLogic removed this from the v3.5.0 milestone Sep 25, 2021
Copy link

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Jan 31, 2024
@dstansby dstansby added keep Items to be ignored by the “Stale” Github Action and removed status: inactive Marked by the “Stale” Github Action labels Jan 31, 2024
@dstansby
Copy link
Member

Still seems to be an issue on current main, so I'll keep this open.

@timhoffm
Copy link
Member

Since plot_date is discouraged anyway, it’s unlikely that we’ll change behavior.

I suggest we close this by better documenting, that tz is only used for axis_date, so affects the axis labeling, but does not directly imply the timezone of the data.

@dstansby
Copy link
Member

I'm guessing this is still and issue with plain plot() though, and I don't see why taking the timezone into account when doing the unit conversion isn't a valid feature request (or even a bug fix)?

@timhoffm
Copy link
Member

Ok, but then let’s rephrase this into a new issue using plot only.

@rcomer
Copy link
Member

rcomer commented Jan 31, 2024

With v3.8.2 I have

import pytz
import matplotlib.pyplot as plt
from datetime import datetime

time_index_berlin = [pytz.timezone('Europe/Berlin').localize(datetime(year=2015, month=11, day=27, hour=x)) for x in range(4)]
time_index_utc = [pytz.timezone('UTC').localize(datetime(year=2015, month=11, day=27, hour=x)) for x in range(4)]


fig, ax = plt.subplots()

ax.plot(time_index_berlin, [4]*4, label='Berlin')
ax.plot(time_index_utc, [3]*4, label='UTC')

ax.legend()
fig.autofmt_xdate()

plt.show()

image

If I reverse the order of plotting:

ax.plot(time_index_utc, [3]*4, label='UTC')
ax.plot(time_index_berlin, [4]*4, label='Berlin')

image

So it seems we plot in whichever timezone came first.

@timhoffm
Copy link
Member

it seems we plot in whichever timezone came first.

Which is reasonable. So, if I understand correctly, we don’t have an issue with pure plot().

@dstansby
Copy link
Member

Ah fair enough, sorry for not checking... if we're not fixing anything on plot_date() now happy for this to be closed as wont fix 👍

@jklymak
Copy link
Member

jklymak commented Jan 31, 2024

I'm confused - are we saying plot_date is broken, but plot works? I wasn't aware plot_date did anything different that plot.

@dstansby
Copy link
Member

dstansby commented Jan 31, 2024

Yet again, my bad for not actually checking... plot_date does seem to be working fine if given dates with different timezones. But this issue is about the tz argument to plot_date which AFAIK has no equivalent with plot?

(as an aside, in the above plot #8072 (comment) I'm a bit confused, isn't Berlin one hour ahead of UTC, which means the lines are the wrong way round (Berlin should be one hour to the right of UTC instead of one hour to the left)??)

@rcomer
Copy link
Member

rcomer commented Jan 31, 2024

Confirmed, plot errors if you pass it the tz parameter.

Yes, Berlin is an hour ahead of UTC (in winter). So when it's midnight in Berlin, it's only 11pm UTC. So I think the plot is correct (note both lines start at midnight).

@ksunden
Copy link
Member

ksunden commented Jan 31, 2024

if xdate:
self.xaxis_date(tz)
if ydate:
self.yaxis_date(tz)
return self.plot(x, y, fmt, **kwargs)

This is the implementation of plot_date as it stands.

The consequences of this implementation are as follows:

  • Only the last tz passed is used and is used to interpret all floating point inputs (regardless of what tz was passed with a particular floating point input)
    • we do not add the tz to the source data, just set it as the active interpretation of floats
  • If no tz is provided, it will use the :rc:timezone (defaults to UTC)
  • datetime objects will still translate to the timezone as they hold their timezone info themselves
  • datetime64 does not store timezone info (though will parse it)... there is some handling of datetime64 in date2num/num2date that looks like there either was once some tz info or is on some sub dtypes we support (pandas?, not sure, but astimezone is not a numpy thing)
    • As such, I believe they are always interpreted as UTC, but might be :rc:timezone, didn't spend the time to differentiate that.
  • float inputs will change (since changing the tz changes what the floating point number isformatted as/translates to as a date, and the tz is not attached to it.

The equivalent to passing the tz argument is to call ax.xaxis_date(tz) (or y axis, but by default x is the only one set).

So, in the example, both plots are using datetime objects which are carrying timezone information as the x values... I do not think we should be applying a new timezone to them in plot_date when they are given as timezoned values. I could see an argument for attaching the tz to float inputs (e.g. by instead of doing self.plot(x, y, **kwargs) doing self.plot(num2date(x, tz=tz), y, **kwargs) (modulo x and y bool flag handling...) but even that I would think would only apply to float inputs, not datetime inputs as is here... and even then am not sure it's actually expected behavior)

Given the admonition that very explicitly states "Do not use this for datetime inputs, use plot instead" (in current mpl, such text was not present when this issue was opened in fairness), my opinion is that this should be closed as "expected behavior". The admonition (which was added in #18346) also does give information about calling axis_date (though does reach in to the axis instead of using the axes method which exists... but just is a wrapper so doesn't really change anything)

@jklymak
Copy link
Member

jklymak commented Jan 31, 2024

I do wonder if we should go a step further and hard deprecate this method. Datetime with timezones are confusing enough without slightly different semantics.

@rcomer
Copy link
Member

rcomer commented Jan 31, 2024

From the discussion at #18346, it seems the intention at the time had been to pre-deprecate plot_date but the PendingDeprecationWarning was causing an issue with Sphinx 👀

@timhoffm
Copy link
Member

I'm fine with deprecating now. We've even already announced that we we will do this in the admonition at https://matplotlib.org/devdocs/api/_as_gen/matplotlib.axes.Axes.plot_date.html#matplotlib.axes.Axes.plot_date

@rcomer rcomer mentioned this issue Mar 3, 2024
4 tasks
@QuLogic QuLogic modified the milestones: future releases, v3.9.0 Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
keep Items to be ignored by the “Stale” Github Action topic: date handling topic: units and array ducktypes
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants