You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
plot_date() after axhline() doesn't rescale axes #7742
@Shang-Jia
I understand that you are in UTSC, I just wanted to remind you that we are all doing this as a part of course work, and it would be against course (and possibly university's) policies to look at another student's code before submission deadline. Your comment above indicates that this is what you did.
To matplotlib developers: Thank you for all the feedback. Unfortunately, to me it seems that some of my classmates are trying to take credit for most of my fix by making minor improvements to it. In fact, I do have a better solution in mind, which I will start working on once the situation above is resolved.
In [3]: matplotlib.__version__
Out[3]: '3.3.0rc1.post273+gb803891a4b'
It looks like we have code in master that is designed to handle this (autoscaling with the mixed transform should be leaving x limits scaling alone), but the original example now yields a traceback:
TypeError Traceback (most recent call last)
<ipython-input-1-01cdab9ed12b> in <module>
5
6 axs[0].axhline(1.5)
----> 7 axs[0].plot([datetime(2016, 1, 1, 0, 0, 0), datetime(2016, 1, 2, 0, 0, 0)], [1, 2])
8
9 axs[1].plot([datetime(2016, 1, 1, 0, 0, 0), datetime(2016, 1, 2, 0, 0, 0)], [1, 2])
~/work/programs/py/mpl/matplotlib/lib/matplotlib/axes/_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
1743 lines = [*self._get_lines(*args, data=data, **kwargs)]
1744 for line in lines:
-> 1745 self.add_line(line)
1746 self._request_autoscale_view(scalex=scalex, scaley=scaley)
1747 return lines
~/work/programs/py/mpl/matplotlib/lib/matplotlib/axes/_base.py in add_line(self, line)
1975 line.set_clip_path(self.patch)
1976
-> 1977 self._update_line_limits(line)
1978 if not line.get_label():
1979 line.set_label('_line%d' % len(self.lines))
~/work/programs/py/mpl/matplotlib/lib/matplotlib/axes/_base.py in _update_line_limits(self, line)
1997 Figures out the data limit of the given line, updating self.dataLim.
1998 """
-> 1999 path = line.get_path()
2000 if path.vertices.size == 0:
2001 return
~/work/programs/py/mpl/matplotlib/lib/matplotlib/lines.py in get_path(self)
1009 """
1010 if self._invalidy or self._invalidx:
-> 1011 self.recache()
1012 return self._path
1013
~/work/programs/py/mpl/matplotlib/lib/matplotlib/lines.py in recache(self, always)
651 if always or self._invalidx:
652 xconv = self.convert_xunits(self._xorig)
--> 653 x = _to_unmasked_float_array(xconv).ravel()
654 else:
655 x = self._x
~/work/programs/py/mpl/matplotlib/lib/matplotlib/cbook/__init__.py in _to_unmasked_float_array(x)
1296 return np.ma.asarray(x, float).filled(np.nan)
1297 else:
-> 1298 return np.asarray(x, float)
1299
1300
~/miniconda3/envs/mpl1/lib/python3.7/site-packages/numpy/core/_asarray.py in asarray(a, dtype, order)
83
84 """
---> 85 return array(a, dtype, copy=False, order=order)
86
87
TypeError: float() argument must be a string or a number, not 'datetime.datetime'
This isn't just dates, this is all units. Basically if the units change on an axes (as they do here from no units to date units) axis.update_info is called, before the new plot artists are added. This calls axis.set_default_interval, and the dataLim is set to the default for the converter, which for dates is 2000-2010.
This doesn't happen if the new plot has no units. the xlims correctly remain -np.Inf, +np.Inf and the relimit works as expected.
I don't know whyaxis.set_default_intervals is called. And this is the only place in the code where it is called. So I think we should just not call it here either.
Thanks to everyone who worked on fixing this! I remember opening this in the early days of my contributions to Matplotlib, so great to finally see it fixed!
Activity
Yasaman-Mah commentedon Feb 28, 2017
I think I have a fix for this, after making the fix, the script above results in:

But I'm not sure how to write tests for it. Are they needed?
phobson commentedon Feb 28, 2017
@Yasaman-Mah
In this is case, I would write a test confirming that both axes have the expected limits:
I think it'd be fine to place this in
matplotlib/lib/tests/test_axes.pytacaswell commentedon Mar 1, 2017
@Yasaman-Mah Looking forward to seeing your PR!
fix matplotlib#7742
Shang-Jia commentedon Mar 6, 2017
@Yasaman-Mah
Plotting again after axhline causes the x-axis to go only up to 2016-01-10 instead of expected 2016-01-30
Fixes matplotlib#7742 - axhline rescale issue
sughandj commentedon Mar 7, 2017
I also encountered what @Shang-Jia said and I have submitted a PR #8210 that fixes all issues discussed.
Yasaman-Mah commentedon Mar 8, 2017
@Shang-Jia
I understand that you are in UTSC, I just wanted to remind you that we are all doing this as a part of course work, and it would be against course (and possibly university's) policies to look at another student's code before submission deadline. Your comment above indicates that this is what you did.
To matplotlib developers: Thank you for all the feedback. Unfortunately, to me it seems that some of my classmates are trying to take credit for most of my fix by making minor improvements to it. In fact, I do have a better solution in mind, which I will start working on once the situation above is resolved.
Merge pull request #3 from sughandj/issue7742_axhline_limits
Merge pull request #4 from ibnIrshad/fix7742
9 remaining items
efiring commentedon Jul 14, 2020
It looks like we have code in master that is designed to handle this (autoscaling with the mixed transform should be leaving x limits scaling alone), but the original example now yields a traceback:
jklymak commentedon Jul 14, 2020
@efiring, that's because on master the date unit converter is not being registered. If you merge #17869 that will be fixed 😉
jklymak commentedon Jul 14, 2020
(ahem, or if you register the date converter manually)
efiring commentedon Jul 15, 2020
Merged and verified: the bug reported here still exists.
jklymak commentedon May 6, 2021
This isn't just dates, this is all units. Basically if the units change on an axes (as they do here from no units to date units)
axis.update_infois called, before the newplotartists are added. This callsaxis.set_default_interval, and thedataLimis set to the default for the converter, which for dates is 2000-2010.This doesn't happen if the new
plothas no units. the xlims correctly remain-np.Inf, +np.Infand the relimit works as expected.I don't know why
axis.set_default_intervalsis called. And this is the only place in the code where it is called. So I think we should just not call it here either.dstansby commentedon Jun 1, 2021
Thanks to everyone who worked on fixing this! I remember opening this in the early days of my contributions to Matplotlib, so great to finally see it fixed!