Skip to content

Commit f49d364

Browse files
committed
MNT: simplify valid tick logic
1 parent 521b60a commit f49d364

10 files changed

+22
-48
lines changed

lib/matplotlib/axis.py

+13-45
Original file line numberDiff line numberDiff line change
@@ -1051,60 +1051,28 @@ def _update_ticks(self, renderer):
10511051
ihigh = locs[-1]
10521052
tick_tups = [ti for ti in tick_tups if ilow <= ti[1] <= ihigh]
10531053

1054-
# so that we don't lose ticks on the end, expand out the interval ever
1055-
# so slightly. The "ever so slightly" is defined to be the width of a
1056-
# half of a pixel. We don't want to draw a tick that even one pixel
1057-
# outside of the defined axis interval.
1058-
if interval[0] <= interval[1]:
1059-
interval_expanded = interval
1060-
else:
1061-
interval_expanded = interval[1], interval[0]
1062-
1063-
if hasattr(self, '_get_pixel_distance_along_axis'):
1064-
# normally, one does not want to catch all exceptions that
1065-
# could possibly happen, but it is not clear exactly what
1066-
# exceptions might arise from a user's projection (their
1067-
# rendition of the Axis object). So, we catch all, with
1068-
# the idea that one would rather potentially lose a tick
1069-
# from one side of the axis or another, rather than see a
1070-
# stack trace.
1071-
# We also catch users warnings here. These are the result of
1072-
# invalid numpy calculations that may be the result of out of
1073-
# bounds on axis with finite allowed intervals such as geo
1074-
# projections i.e. Mollweide.
1075-
with np.errstate(invalid='ignore'):
1076-
try:
1077-
ds1 = self._get_pixel_distance_along_axis(
1078-
interval_expanded[0], -0.5)
1079-
except Exception:
1080-
warnings.warn("Unable to find pixel distance along axis "
1081-
"for interval padding of ticks; assuming no "
1082-
"interval padding needed.")
1083-
ds1 = 0.0
1084-
if np.isnan(ds1):
1085-
ds1 = 0.0
1086-
try:
1087-
ds2 = self._get_pixel_distance_along_axis(
1088-
interval_expanded[1], +0.5)
1089-
except Exception:
1090-
warnings.warn("Unable to find pixel distance along axis "
1091-
"for interval padding of ticks; assuming no "
1092-
"interval padding needed.")
1093-
ds2 = 0.0
1094-
if np.isnan(ds2):
1095-
ds2 = 0.0
1096-
interval_expanded = (interval_expanded[0] - ds1,
1097-
interval_expanded[1] + ds2)
1054+
if interval[1] <= interval[0]:
1055+
interval = interval[1], interval[0]
1056+
inter = self.get_transform().transform(interval)
10981057

10991058
ticks_to_draw = []
11001059
for tick, loc, label in tick_tups:
1060+
# draw each tick if it is in interval. Note the transform
1061+
# to pixel space to take care of log transforms etc.
1062+
# interval_contains has a floating point tolerance.
11011063
if tick is None:
11021064
continue
11031065
# NB: always update labels and position to avoid issues like #9397
11041066
tick.update_position(loc)
11051067
tick.set_label1(label)
11061068
tick.set_label2(label)
1107-
if not mtransforms.interval_contains(interval_expanded, loc):
1069+
try:
1070+
loct = self.get_transform().transform(loc)
1071+
except AssertionError:
1072+
loct = None
1073+
continue
1074+
if ((loct is None) or
1075+
(not mtransforms.interval_contains(inter, loct))):
11081076
continue
11091077
ticks_to_draw.append(tick)
11101078

lib/matplotlib/transforms.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -2892,7 +2892,7 @@ def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True):
28922892
return vmin, vmax
28932893

28942894

2895-
def interval_contains(interval, val):
2895+
def interval_contains(interval, val, rtol=1e-10):
28962896
"""
28972897
Check, inclusively, whether an interval includes a given value.
28982898
@@ -2902,14 +2902,20 @@ def interval_contains(interval, val):
29022902
A 2-length sequence, endpoints that define the interval.
29032903
val : scalar
29042904
Value to check is within interval.
2905+
rtol : scalar
2906+
Tolerance slippage allowed outside of this interval. Default
2907+
1e-10 * (b - a).
29052908
29062909
Returns
29072910
-------
29082911
bool
2909-
Returns true if given val is within the interval.
2912+
Returns true if given val is within the interval (with tolerance)
29102913
"""
29112914
a, b = interval
2912-
return a <= val <= b or a >= val >= b
2915+
if a > b:
2916+
a, b = b, a
2917+
rtol = (b - a) * rtol
2918+
return a - rtol <= val <= b + rtol
29132919

29142920

29152921
def interval_contains_open(interval, val):

0 commit comments

Comments
 (0)