{"record":{"id":"c8f009695ca4bc01","repo":"matplotlib/matplotlib","slug":"cannot-get-window-extent-of-text-w-o-renderer-you","errorCode":null,"errorMessage":"Cannot get window extent of text w/o renderer. You likely want to call 'figure.draw_without_rendering()' first.","messagePattern":"Cannot get window extent of text w/o renderer\\. You likely want to call 'figure\\.draw_without_rendering\\(\\)' first\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/matplotlib/text.py","lineNumber":1071,"sourceCode":"            e.g. if to match regions with a figure saved with a custom dpi value.\n        \"\"\"\n        if not self.get_visible():\n            return Bbox.unit()\n\n        fig = self.get_figure(root=True)\n        if dpi is None:\n            dpi = fig.dpi\n        if self.get_text() == '':\n            with cbook._setattr_cm(fig, dpi=dpi):\n                tx, ty = self._get_xy_display()\n                return Bbox.from_bounds(tx, ty, 0, 0)\n\n        if renderer is not None:\n            self._renderer = renderer\n        if self._renderer is None:\n            self._renderer = fig._get_renderer()\n        if self._renderer is None:\n            raise RuntimeError(\n                \"Cannot get window extent of text w/o renderer. You likely \"\n                \"want to call 'figure.draw_without_rendering()' first.\")\n\n        with cbook._setattr_cm(fig, dpi=dpi):\n            bbox, _, _ = self._get_layout(self._renderer)\n            x, y = self.get_unitless_position()\n            x, y = self.get_transform().transform((x, y))\n            bbox = bbox.translated(x, y)\n            return bbox\n\n    def get_tightbbox(self, renderer=None):\n        if not self.get_visible() or self.get_text() == \"\":\n            return Bbox.null()\n        # Exclude text at data coordinates outside the valid domain of the axes\n        # scales (e.g., negative coordinates with a log scale).\n        if (self.axes\n                and self.get_transform() == self.axes.transData\n                and not self.axes._point_in_data_domain(*self.get_unitless_position())):","sourceCodeStart":1053,"sourceCodeEnd":1089,"githubUrl":"https://github.com/matplotlib/matplotlib/blob/b379c1b69e012b142c0f496a52bcb30513802d72/lib/matplotlib/text.py#L1053-L1089","documentation":"Text.get_window_extent() (lib/matplotlib/text.py) needs a renderer to measure glyph sizes. If the caller passes none, it tries the renderer stored on the Text and then the figure's fig._get_renderer(); when both are None (typically a figure whose canvas cannot supply a renderer before any draw), this RuntimeError is raised with the recommended fix in the message: call figure.draw_without_rendering() first.","triggerScenarios":"text.get_window_extent() with no argument on a figure that has never been drawn; measuring text on a canvas that does not provide a renderer until draw (some non-GUI or partially initialized backends); code that previously passed a renderer but now runs headless; empty-string shortcuts do not hit this - any non-empty text does.","commonSituations":"Computing label bboxes to size a figure before saving (savefig with bbox_inches='tight' does this for you); headless report-generation pipelines that call get_window_extent on fresh figures; upgrading code from older matplotlib where a stale self._renderer happened to survive.","solutions":["Call fig.draw_without_rendering() once before measuring, as the message suggests - this initializes a renderer without producing an image file.","Or pass the renderer explicitly: t.get_window_extent(fig.canvas.get_renderer()) on Agg-based backends.","Or trigger a real draw first (fig.canvas.draw()) if you are rendering anyway.","For savefig-only workflows, use bbox_inches='tight' and let matplotlib handle measurement."],"exampleFix":"# before\nfig, ax = plt.subplots()\nt = ax.set_title('measure me')\nbbox = t.get_window_extent()  # RuntimeError: no renderer\n\n# after\nfig.draw_without_rendering()\nbbox = t.get_window_extent()","handlingStrategy":"validation","validationCode":"# ensure a renderer exists before measuring any Text\nfig.draw_without_rendering()\n# or explicitly:\nrenderer = fig.canvas.get_renderer()  # Agg-style backends\nbbox = text_obj.get_window_extent(renderer)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make fig.draw_without_rendering() the first step of any measuring code path.","Prefer savefig(bbox_inches='tight') over manual extent math when the goal is tight output.","Pass the renderer explicitly when you already hold one from a draw callback."],"tags":["matplotlib","text","renderer","get-window-extent","runtimeerror"],"backgroundTag":"renderer-not-available","analyzedSha":"b379c1b69e012b142c0f496a52bcb30513802d72","analyzedAt":"2026-08-21T23:31:55.468Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}