Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2443,6 +2443,20 @@ def _add_text(self, txt):
self.stale = True
return txt

def _point_in_data_domain(self, x, y):
"""
Check if the data point (x, y) is within the valid domain of the axes
scales.

Returns False if the point is outside the data range
(e.g. negative coordinates with a log scale).
"""
for val, axis in zip([x, y], self._axis_map.values()):
vmin, vmax = axis.limit_range_for_scale(val, val)
if vmin != val or vmax != val:
return False
return True

def _update_line_limits(self, line):
"""
Figures out the data limit of the given line, updating `.Axes.dataLim`.
Expand Down
12 changes: 12 additions & 0 deletions lib/matplotlib/tests/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -1226,3 +1226,15 @@ def test_ytick_rotation_mode():
tick.set_rotation(angle)

plt.subplots_adjust(left=0.4, right=0.6, top=.99, bottom=.01)


def test_text_tightbbox_outside_scale_domain():
# Test that text at positions outside the valid domain of axes scales
# (e.g., negative coordinates with log scale) returns a null bbox.
fig, ax = plt.subplots()
ax.set_yscale('log')
ax.set_ylim(1, 100)

invalid_text = ax.text(0, -5, 'invalid')
invalid_bbox = invalid_text.get_tightbbox(fig.canvas.get_renderer())
assert not np.isfinite(invalid_bbox.width)
9 changes: 9 additions & 0 deletions lib/matplotlib/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,15 @@ def get_window_extent(self, renderer=None, dpi=None):
bbox = bbox.translated(x, y)
return bbox

def get_tightbbox(self, renderer=None):
# Exclude text at data coordinates outside the valid domain of the axes
# scales (e.g., negative coordinates with a log scale).
if (self.axes
and self.get_transform() == self.axes.transData
and not self.axes._point_in_data_domain(*self.get_unitless_position())):
return Bbox.null()
return super().get_tightbbox(renderer)

def set_backgroundcolor(self, color):
"""
Set the background color of the text.
Expand Down
Loading