-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
misplaced spines in dates plot #7138
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
Comments
wow, that's a doozy. does this still happen in 2.0b4 with |
It is x-spine shift. Open the plot, make the window wide and then slowly resize it - you will see. |
You can't tell if it is an x or y spine shift to the right or left just by looking at one image. It has to be compared to a baseline - hence why classic mode would be helpful here since fonts and other settings have changed that would complicate direct comparisons. |
It does not happen in classic mode for me. |
If you pan and zoom, the x spine jumps between alignment with the y spine and how it looks here. The y spine does not shift position. |
It doesn't happen in classic mode with these axes limits for me, but if you pan around enough, it does happen in classic mode. |
Try to resize the window |
Upon further investigation this is indeed because of floating point inaccuracies: indeed, the spines are off by a few ms, which is ~10e-14 relative to the 2000y timedelta (given that the times are internally in floating point days relative to year 1); specifically the inaccuracy occurs when the transLimits and transAxes matrices are multiplied together first (essentially it's (transAxestransLimits)limits vs transAxes(transLimitslimits)). I don't think there's much to do for matplotlib floating point datetimes per se; however this should not occur when using numpy datetimes (which do not suffer from this inaccuracy problem and can represent microseconds over tens of thousands of years exactly (https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html#datetime-units) -- but because we internally convert them to matplotlib dates, all is lost. May be worth checking whether we can have a parallel system (well, reusing as much machinery as possible) that uses numpy datetimes internally. |
We have to convert to float at some point. That involves an inherent loss in resolution over a given date range. As pointed out numerous times, using matplotlib date plotting on timescales shorter than milliseconds will lead to inaccuracies and the user should just plot as seconds from the start of the day, or some other reference time. I really don’t think there is any advantage to specially handling dates at such a small scale. |
I'm actually fine with saying "we can't do anything about it", but I think if we can't even position plot elements accurately (if spines are at the wrong place it seems likely that other artists will be rendered at the wrong place too) then we should just error out. Or at least reword the warning in #15000 to something stronger: it's not that plotting microseconds at current reference times is "not well supported", it's that the plot may well have nothing to do with your actual data. |
That'd be fine. But we don't error out on other floating point inaccuracies, its just that this one is more unexpected. One thing we could do is change the epoch to something more modern, like 1970, or 2000. Most people plotting old dates do not need millisecond accuracy. |
OK, what do you think about an |
I guess that may be nice to have. |
I did it. It works, down the point the microsecond locator gives up. But... we lose some guard-rails, like matplotlib times can't be less than 1. OTOH, not sure why that's really needed or desirable. |
I guess I'm still somewhat of the opinion that if you are going to go to the trouble of specifying an epoch, you might as well just subtract the epoch from the time and plot as floats yourself, but I could be convinced otherwise. |
Well we can still say "put your epoch to somewhere earlier than any date you're planning to use" and call it a day. We can even make date2num and friends set a global variable "a date conversion has been done" and make set_epoch error out if any date conversion has already been done (so that we don't end up with inconsistent epochs). However I certainly also agree we may be overengineering this. |
This should be fixed by #15008, assuming you use a recent epoch. |
Noticed while investigating the test failure in #7123.
1.5.3:


2.0b4:
Note how the horizontal spines are shifted in 2.0b4.
The text was updated successfully, but these errors were encountered: