| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| ``AutoDateLocator.get_locator`` now contains reduced datetime overlaps | ||
| ```````````````````````````````````````````````````````````````````````` | ||
|
|
||
| Due to issue #7712, the interval frequency of datetime ticks gets reduced due to | ||
| avoid overlapping tick labels. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -1208,12 +1208,20 @@ def __init__(self, tz=None, minticks=5, maxticks=None, | |
| The interval is used to specify multiples that are appropriate for | ||
| the frequency of ticking. For instance, every 7 days is sensible | ||
| for daily ticks, but for minutes/seconds, 15 or 30 make sense. | ||
| You can customize this dictionary by doing:: | ||
| You can customize this dictionary by doing: | ||
|
|
||
| locator = AutoDateLocator() | ||
| locator.intervald[HOURLY] = [3] # only show every 3 hours | ||
|
|
||
| In order to avoid overlapping dates, another dictionary was | ||
| created to map date intervals to the format of the date used in | ||
| rcParams. In addition, the figsize and font is used from the axis, | ||
| and a new setting in rcparams['autodatelocator.spacing'] is added | ||
| and used to let the user decide when spacing should be used. This | ||
| was done because rotation at this point in runtime is not known. | ||
| """ | ||
| DateLocator.__init__(self, tz) | ||
|
|
||
| self._locator = YearLocator() | ||
| self._freq = YEARLY | ||
| self._freqs = [YEARLY, MONTHLY, DAILY, HOURLY, MINUTELY, | ||
| Expand Down Expand Up | @@ -1242,6 +1250,16 @@ def __init__(self, tz=None, minticks=5, maxticks=None, | |
| MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, | ||
| 5000, 10000, 20000, 50000, 100000, 200000, 500000, | ||
| 1000000]} | ||
|
|
||
| self.eachtick = { | ||
| YEARLY: rcParams['date.autoformatter.year'], | ||
| MONTHLY: rcParams['date.autoformatter.month'], | ||
| DAILY: rcParams['date.autoformatter.day'], | ||
| HOURLY: rcParams['date.autoformatter.hour'], | ||
| MINUTELY: rcParams['date.autoformatter.minute'], | ||
| SECONDLY: rcParams['date.autoformatter.second'], | ||
| MICROSECONDLY: rcParams['date.autoformatter.microsecond']} | ||
|
|
||
| self._byranges = [None, range(1, 13), range(1, 32), | ||
| range(0, 24), range(0, 60), range(0, 60), None] | ||
|
|
||
| Expand Down Expand Up | @@ -1314,11 +1332,34 @@ def get_locator(self, dmin, dmax): | |
| # bysecond, unused (for microseconds)] | ||
| byranges = [None, 1, 1, 0, 0, 0, None] | ||
|
|
||
| # Required attributes to get width from figure's normal points | ||
| axis_name = getattr(self.axis, 'axis_name', '') | ||
| axes = getattr(self.axis, 'axes', None) | ||
| label = getattr(self.axis, 'label', None) | ||
| figure = getattr(self.axis, 'figure', None) | ||
| transfig = getattr(figure, 'transFigure', None) | ||
| maxwid = rcParams['figure.figsize'][0] | ||
|
|
||
| # estimated font ratio on font size 10 | ||
| if label is not None: | ||
| font_ratio = label.get_fontsize() / 10 | ||
| else: | ||
| font_ratio = rcParams['font.size'] / 10 | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI'm pretty sure the ticks have a fontsize associated with them beyond the label fontsize. THats the fontsize you should querry, and I'm pretty sure it exists.
Sorry, something went wrong.
All reactions
|
||
|
|
||
| # a ratio of 8 date characters per inch is 'estimated' | ||
| if (axes is not None and transfig is not None): | ||
| bbox = axes.get_position(original=False) | ||
| figwidth = transfig.transform(bbox.get_points())[1][0] | ||
| dpi = figure.get_dpi() | ||
| maxwid = (figwidth / dpi) * 8 | ||
|
|
||
| spacing = (rcParams["autodatelocator.spacing"] == "generous") | ||
|
|
||
| # Loop over all the frequencies and try to find one that gives at | ||
| # least a minticks tick positions. Once this is found, look for | ||
| # an interval from an list specific to that frequency that gives no | ||
| # more than maxticks tick positions. Also, set up some ranges | ||
| # (bymonth, etc.) as appropriate to be passed to rrulewrapper. | ||
| # (bymonth, etc.) as appropriate to be passed to rrulewrapper | ||
| for i, (freq, num) in enumerate(zip(self._freqs, nums)): | ||
| # If this particular frequency doesn't give enough ticks, continue | ||
| if num < self.minticks: | ||
| Expand All | @@ -1328,11 +1369,24 @@ def get_locator(self, dmin, dmax): | |
| byranges[i] = None | ||
| continue | ||
|
|
||
| # Compute at runtime the size of date label with given format | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualityagain, this should only happen if spacing is on.
Sorry, something went wrong.
All reactions
|
||
| if (axis_name == 'x'): | ||
| datelen_ratio = \ | ||
| len(dmin.strftime(self.eachtick[freq])) * font_ratio | ||
| else: | ||
| datelen_ratio = 1 * font_ratio | ||
|
|
||
| # Find the first available interval that doesn't give too many | ||
| # ticks | ||
| for interval in self.intervald[freq]: | ||
| if num <= interval * (self.maxticks[freq] - 1): | ||
| break | ||
|
|
||
| # Using an estmation of characters per inch, reduce | ||
| # intervals untill we get no overlaps | ||
| apply_spread = (not spacing or | ||
| ((num/interval) * datelen_ratio) <= maxwid) | ||
| if (num <= interval * (self.maxticks[freq] - 1)): | ||
| if (apply_spread): | ||
| break | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality??? I don't understand why you only break if apply_spread=True here.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWhen users have rotated labels we shouldn't apply spread, it applies too much spacing. Unfortunately this is why i added to Rcparams in the first place
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityBut you need "interval" to be correct for byranges, below.
Sorry, something went wrong.
All reactions
|
||
| else: | ||
| # We went through the whole loop without breaking, default to | ||
| # the last interval in the list and raise a warning | ||
| Expand All | @@ -1344,7 +1398,6 @@ def get_locator(self, dmin, dmax): | |
|
|
||
| # Set some parameters as appropriate | ||
| self._freq = freq | ||
|
|
||
| if self._byranges[i] and self.interval_multiples: | ||
| byranges[i] = self._byranges[i][::interval] | ||
| interval = 1 | ||
| Expand Down | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -352,6 +352,8 @@ backend : $TEMPLATE_BACKEND | |
| #date.autoformatter.second : %H:%M:%S | ||
| #date.autoformatter.microsecond : %M:%S.%f | ||
|
|
||
| #autodatelocator.spacing : tight ## if generous, add extra spacing to avoid overlap, otherwise tight | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityMaybe autodatelocator.generousspacing : False True/False would be a cleaner API?
Sorry, something went wrong.
All reactions
|
||
|
|
||
| #### TICKS | ||
| ## see http://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick | ||
| #xtick.top : False ## draw ticks on the top side | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI think this should all be wrapped in if spacing:
I don't get why you are using getattr for all these. If these attributes don't exist, you might as well error here because you weren't passed an axis...
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIf we raise exceptions it would break existing tests using mock classes that might have aaxis attributes as none.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWhich tests? I don't understand what a test would be doing down in here w/o the axes being set (for instance).
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualityfor example test_dates.py::def test_auto_date_locator(), this uses dummy axis to specifically check values returned from autodatelocator. It has a few none axis attributes
https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/tests/test_dates.py#L320
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityOK, well I'd just check if whichever one of these is None and set spacing=False if that happens
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.