Bug summary
Adding an AnchoredText instance directly to a Figure via fig.add_artist() causes an AttributeError when plt.show() attempts to render the canvas.
Code for reproduction
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredText
fig, ax = plt.subplots()
fig.add_artist(AnchoredText("Example", loc='upper right'))
plt.show()
Actual outcome
AttributeError Traceback (most recent call last)
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/backend_bases.py:2332, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2329 # we do this instead of self.figure.draw_without_rendering
2330 # so that we can inject the orientation
2331 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2332 self.figure.draw(renderer)
2333 else:
2334 renderer = None
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/artist.py:137, in _finalize_rasterization..draw_wrapper(artist, renderer, *args, **kwargs)
135 @wraps(draw)
136 def draw_wrapper(artist, renderer, *args, **kwargs):
--> 137 result = draw(artist, renderer, *args, **kwargs)
138 if renderer._rasterizing:
139 renderer.stop_rasterizing()
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/artist.py:114, in allow_rasterization..draw_wrapper(artist, renderer)
111 if artist.get_agg_filter() is not None:
112 renderer.start_filter()
--> 114 return draw(artist, renderer)
115 finally:
116 if artist.get_agg_filter() is not None:
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/figure.py:3362, in Figure.draw(self, renderer)
3359 # ValueError can occur when resizing a window.
3361 self.patch.draw(renderer)
-> 3362 mimage._draw_list_compositing_images(
3363 renderer, self, artists, self.suppressComposite)
3365 renderer.close_group('figure')
3366 finally:
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
131 if not_composite or not has_images:
132 for a in artists:
--> 133 a.draw(renderer)
134 else:
135 # Composite any adjacent images together
136 image_group = []
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/artist.py:81, in _prevent_rasterization..draw_wrapper(artist, renderer, *args, **kwargs)
78 renderer.stop_rasterizing()
79 renderer._rasterizing = False
---> 81 return draw(artist, renderer, *args, **kwargs)
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:1092, in AnchoredOffsetbox.draw(self, renderer)
1089 return
1091 # update the location and size of the legend
-> 1092 bbox = self.get_window_extent(renderer)
1093 fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
1094 self.update_frame(bbox, fontsize)
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:369, in OffsetBox.get_window_extent(self, renderer)
367 bbox = self.get_bbox(renderer)
368 try: # Some subclasses redefine get_offset to take no args.
--> 369 px, py = self.get_offset(bbox, renderer)
370 except TypeError:
371 px, py = self.get_offset()
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:60, in _compat_get_offset..get_offset(self, *args, **kwargs)
56 params = _api.select_matching_signature(sigs, self, *args, **kwargs)
57 bbox = (params["bbox"] if "bbox" in params else
58 Bbox.from_bounds(-params["xdescent"], -params["ydescent"],
59 params["width"], params["height"]))
---> 60 return meth(params["self"], bbox, params["renderer"])
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:1071, in AnchoredOffsetbox.get_offset(self, bbox, renderer)
1069 pad_x_pixels = borderpad_x * fontsize_in_pixels
1070 pad_y_pixels = borderpad_y * fontsize_in_pixels
-> 1071 bbox_to_anchor = self.get_bbox_to_anchor()
1072 x0, y0 = _get_anchored_bbox(
1073 self.loc,
1074 Bbox.from_bounds(0, 0, bbox.width, bbox.height),
(...) 1077 pad_y_pixels
1078 )
1079 return x0 - bbox.x0, y0 - bbox.y0
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:1027, in AnchoredOffsetbox.get_bbox_to_anchor(self)
1025 """Return the bbox that the box is anchored to."""
1026 if self._bbox_to_anchor is None:
-> 1027 return self.axes.bbox
1028 else:
1029 transform = self._bbox_to_anchor_transform
AttributeError: 'NoneType' object has no attribute 'bbox'
Expected outcome
Additional information
No response
Operating system
No response
Matplotlib Version
0.2.0.dev55193+unknown.g2153774ae
Matplotlib Backend
No response
Python version
No response
Jupyter version
No response
Installation
None
Bug summary
Adding an AnchoredText instance directly to a Figure via fig.add_artist() causes an AttributeError when plt.show() attempts to render the canvas.
Code for reproduction
Actual outcome
AttributeError Traceback (most recent call last)
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/backend_bases.py:2332, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2329 # we do this instead of
self.figure.draw_without_rendering2330 # so that we can inject the orientation
2331 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2332 self.figure.draw(renderer)
2333 else:
2334 renderer = None
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/artist.py:137, in _finalize_rasterization..draw_wrapper(artist, renderer, *args, **kwargs)
135 @wraps(draw)
136 def draw_wrapper(artist, renderer, *args, **kwargs):
--> 137 result = draw(artist, renderer, *args, **kwargs)
138 if renderer._rasterizing:
139 renderer.stop_rasterizing()
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/artist.py:114, in allow_rasterization..draw_wrapper(artist, renderer)
111 if artist.get_agg_filter() is not None:
112 renderer.start_filter()
--> 114 return draw(artist, renderer)
115 finally:
116 if artist.get_agg_filter() is not None:
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/figure.py:3362, in Figure.draw(self, renderer)
3359 # ValueError can occur when resizing a window.
3361 self.patch.draw(renderer)
-> 3362 mimage._draw_list_compositing_images(
3363 renderer, self, artists, self.suppressComposite)
3365 renderer.close_group('figure')
3366 finally:
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
131 if not_composite or not has_images:
132 for a in artists:
--> 133 a.draw(renderer)
134 else:
135 # Composite any adjacent images together
136 image_group = []
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/artist.py:81, in _prevent_rasterization..draw_wrapper(artist, renderer, *args, **kwargs)
78 renderer.stop_rasterizing()
79 renderer._rasterizing = False
---> 81 return draw(artist, renderer, *args, **kwargs)
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:1092, in AnchoredOffsetbox.draw(self, renderer)
1089 return
1091 # update the location and size of the legend
-> 1092 bbox = self.get_window_extent(renderer)
1093 fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
1094 self.update_frame(bbox, fontsize)
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:369, in OffsetBox.get_window_extent(self, renderer)
367 bbox = self.get_bbox(renderer)
368 try: # Some subclasses redefine get_offset to take no args.
--> 369 px, py = self.get_offset(bbox, renderer)
370 except TypeError:
371 px, py = self.get_offset()
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:60, in _compat_get_offset..get_offset(self, *args, **kwargs)
56 params = _api.select_matching_signature(sigs, self, *args, **kwargs)
57 bbox = (params["bbox"] if "bbox" in params else
58 Bbox.from_bounds(-params["xdescent"], -params["ydescent"],
59 params["width"], params["height"]))
---> 60 return meth(params["self"], bbox, params["renderer"])
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:1071, in AnchoredOffsetbox.get_offset(self, bbox, renderer)
1069 pad_x_pixels = borderpad_x * fontsize_in_pixels
1070 pad_y_pixels = borderpad_y * fontsize_in_pixels
-> 1071 bbox_to_anchor = self.get_bbox_to_anchor()
1072 x0, y0 = _get_anchored_bbox(
1073 self.loc,
1074 Bbox.from_bounds(0, 0, bbox.width, bbox.height),
(...) 1077 pad_y_pixels
1078 )
1079 return x0 - bbox.x0, y0 - bbox.y0
File ~/Documents/code/dataviz-fuzzing/matplotlib/lib/matplotlib/offsetbox.py:1027, in AnchoredOffsetbox.get_bbox_to_anchor(self)
1025 """Return the bbox that the box is anchored to."""
1026 if self._bbox_to_anchor is None:
-> 1027 return self.axes.bbox
1028 else:
1029 transform = self._bbox_to_anchor_transform
AttributeError: 'NoneType' object has no attribute 'bbox'
Expected outcome
Additional information
No response
Operating system
No response
Matplotlib Version
0.2.0.dev55193+unknown.g2153774ae
Matplotlib Backend
No response
Python version
No response
Jupyter version
No response
Installation
None