Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d23bcea

Browse files
jklymaktimhoffm
authored andcommitted
MNT: simplify valid tick logic (#12158)
FIX: make contains_close private
1 parent 2b86111 commit d23bcea

10 files changed

+45
-49
lines changed

lib/matplotlib/axis.py

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,62 +1017,29 @@ def _update_ticks(self, renderer):
10171017
ihigh = locs[-1]
10181018
tick_tups = [ti for ti in tick_tups if ilow <= ti[1] <= ihigh]
10191019

1020-
# so that we don't lose ticks on the end, expand out the interval ever
1021-
# so slightly. The "ever so slightly" is defined to be the width of a
1022-
# half of a pixel. We don't want to draw a tick that even one pixel
1023-
# outside of the defined axis interval.
1024-
if interval[0] <= interval[1]:
1025-
interval_expanded = interval
1026-
else:
1027-
interval_expanded = interval[1], interval[0]
1028-
1029-
if hasattr(self, '_get_pixel_distance_along_axis'):
1030-
# normally, one does not want to catch all exceptions that
1031-
# could possibly happen, but it is not clear exactly what
1032-
# exceptions might arise from a user's projection (their
1033-
# rendition of the Axis object). So, we catch all, with
1034-
# the idea that one would rather potentially lose a tick
1035-
# from one side of the axis or another, rather than see a
1036-
# stack trace.
1037-
# We also catch users warnings here. These are the result of
1038-
# invalid numpy calculations that may be the result of out of
1039-
# bounds on axis with finite allowed intervals such as geo
1040-
# projections i.e. Mollweide.
1041-
with np.errstate(invalid='ignore'):
1042-
try:
1043-
ds1 = self._get_pixel_distance_along_axis(
1044-
interval_expanded[0], -0.5)
1045-
except Exception:
1046-
cbook._warn_external("Unable to find pixel distance "
1047-
"along axis for interval padding of "
1048-
"ticks; assuming no interval "
1049-
"padding needed.")
1050-
ds1 = 0.0
1051-
if np.isnan(ds1):
1052-
ds1 = 0.0
1053-
try:
1054-
ds2 = self._get_pixel_distance_along_axis(
1055-
interval_expanded[1], +0.5)
1056-
except Exception:
1057-
cbook._warn_external("Unable to find pixel distance "
1058-
"along axis for interval padding of "
1059-
"ticks; assuming no interval "
1060-
"padding needed.")
1061-
ds2 = 0.0
1062-
if np.isnan(ds2):
1063-
ds2 = 0.0
1064-
interval_expanded = (interval_expanded[0] - ds1,
1065-
interval_expanded[1] + ds2)
1020+
if interval[1] <= interval[0]:
1021+
interval = interval[1], interval[0]
1022+
inter = self.get_transform().transform(interval)
10661023

10671024
ticks_to_draw = []
10681025
for tick, loc, label in tick_tups:
1026+
# draw each tick if it is in interval. Note the transform
1027+
# to pixel space to take care of log transforms etc.
1028+
# interval_contains has a floating point tolerance.
10691029
if tick is None:
10701030
continue
10711031
# NB: always update labels and position to avoid issues like #9397
10721032
tick.update_position(loc)
10731033
tick.set_label1(label)
10741034
tick.set_label2(label)
1075-
if not mtransforms.interval_contains(interval_expanded, loc):
1035+
try:
1036+
loct = self.get_transform().transform(loc)
1037+
except AssertionError:
1038+
# transforms.transform doesn't allow masked values but
1039+
# some scales might make them, so we need this try/except.
1040+
loct = None
1041+
continue
1042+
if not mtransforms._interval_contains_close(inter, loct):
10761043
continue
10771044
ticks_to_draw.append(tick)
10781045

lib/matplotlib/transforms.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,10 +2892,39 @@ def interval_contains(interval, val):
28922892
Returns
28932893
-------
28942894
bool
2895-
Returns true if given val is within the interval.
2895+
Returns *True* if given *val* is within the *interval*.
2896+
"""
2897+
a, b = interval
2898+
if a > b:
2899+
a, b = b, a
2900+
return a <= val <= b
2901+
2902+
2903+
def _interval_contains_close(interval, val, rtol=1e-10):
2904+
"""
2905+
Check, inclusively, whether an interval includes a given value, with the
2906+
interval expanded by a small tolerance to admit floating point errors.
2907+
2908+
Parameters
2909+
----------
2910+
interval : sequence of scalar
2911+
A 2-length sequence, endpoints that define the interval.
2912+
val : scalar
2913+
Value to check is within interval.
2914+
rtol : scalar
2915+
Tolerance slippage allowed outside of this interval. Default
2916+
1e-10 * (b - a).
2917+
2918+
Returns
2919+
-------
2920+
bool
2921+
Returns *True* if given *val* is within the *interval* (with tolerance)
28962922
"""
28972923
a, b = interval
2898-
return a <= val <= b or a >= val >= b
2924+
if a > b:
2925+
a, b = b, a
2926+
rtol = (b - a) * rtol
2927+
return a - rtol <= val <= b + rtol
28992928

29002929

29012930
def interval_contains_open(interval, val):

0 commit comments

Comments
 (0)