Comparing Continuous Problems¶
Download this as a Jupyter notebook
This example notebook shows how pyXla distinguishes between the sphere and deceptive problems.
The sphere function is defined as:
and is visualised below:
The deceptive problem function is defined as:
and is visualised below:
Equation (2) is called deceptive because it has two local minima as shown in its visualisation above.
To begin, we load the two problems as samples:
from pyxla import load_data
from pyxla.sampling import HilbertCurveSampler
sphere_sample = {
"name": "Sphere",
"X": HilbertCurveSampler(sample_size=100, dim=1, l_bound=-5, u_bound=5),
"F": lambda x: x**2
}
deceptive_sample = {
"name": "Deceptive",
"X": HilbertCurveSampler(sample_size=100, dim=1, l_bound=0, u_bound=6),
"F": lambda x: (0.4 * x - 2) ** 2 if x > 0.625 else (10 * x - 4) ** 2 - 2
}
load_data(sphere_sample) # loaded in-place
load_data(deceptive_sample) # loaded in-place
WARNING:root:The Hilbert curve with dimension 1 is just a number line. You are sampling around points on a number line.
WARNING:root:The Hilbert curve with dimension 1 is just a number line. You are sampling around points on a number line.
Compare their objective distribution:¶
from pyxla import distr_f
feat, plot = distr_f(sphere_sample)
feat
{'f0_min': 8.389952807188794e-07,
'f0_max': 25.0,
'f0_mean': 8.898275409804137,
'f0_med': 6.624358197535213,
'f0_q1': 1.9693091641610883,
'f0_q3': 15.688997850593484,
'f0_sd': 7.921718016961657,
'f0_skew': 0.5975228746274769,
'f0_kurt': -1.0245736317832672,
'f0_rank_min': 1,
'f0_rank_max': 100,
'f0_rank_mean': 50.5,
'f0_rank_med': 50.5,
'f0_rank_q1': 25.25,
'f0_rank_q3': 75.75,
'f0_rank_sd': 29.011491975882016,
'f0_rank_skew': 0.0,
'f0_rank_kurt': -1.2002400240024003}
Error in callback <function _draw_all_if_interactive at 0x78cde0056e50> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/pyplot.py:300, in _draw_all_if_interactive()
298 def _draw_all_if_interactive() -> None:
299 if matplotlib.is_interactive():
--> 300 draw_all()
File /usr/local/lib/python3.14/site-packages/matplotlib/_pylab_helpers.py:133, in Gcf.draw_all(cls, force)
131 for manager in cls.get_all_fig_managers():
132 if force or manager.canvas.figure.stale:
--> 133 manager.canvas.draw_idle()
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:1989, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
1987 if not self._is_idle_drawing:
1988 with self._idle_draw_cntx():
-> 1989 self.draw(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:438, in FigureCanvasAgg.draw(self)
435 # Acquire a lock on the shared font cache.
436 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
437 else nullcontext()):
--> 438 self.figure.draw(self.renderer)
439 # A GUI class may be need to update a window using this draw, so
440 # don't forget to call the superclass.
441 super().draw()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:2257, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2254 # we do this instead of `self.figure.draw_without_rendering`
2255 # so that we can inject the orientation
2256 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2257 self.figure.draw(renderer)
2258 else:
2259 renderer = None
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
<Figure size 300x600 with 2 Axes>
feat, plot = distr_f(deceptive_sample)
feat
{'f0_min': -1.8170155932769807,
'f0_max': 14.0,
'f0_mean': 1.1484529702827588,
'f0_med': 0.45317411843204913,
'f0_q1': 0.08561601068739254,
'f0_q3': 1.5177705120667428,
'f0_sd': 2.2472649816244052,
'f0_skew': 3.83069634252125,
'f0_kurt': 17.260924362375505,
'f0_rank_min': 1,
'f0_rank_max': 100,
'f0_rank_mean': 50.5,
'f0_rank_med': 50.5,
'f0_rank_q1': 25.25,
'f0_rank_q3': 75.75,
'f0_rank_sd': 29.011491975882016,
'f0_rank_skew': 0.0,
'f0_rank_kurt': -1.2002400240024003}
Error in callback <function _draw_all_if_interactive at 0x78cde0056e50> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/pyplot.py:300, in _draw_all_if_interactive()
298 def _draw_all_if_interactive() -> None:
299 if matplotlib.is_interactive():
--> 300 draw_all()
File /usr/local/lib/python3.14/site-packages/matplotlib/_pylab_helpers.py:133, in Gcf.draw_all(cls, force)
131 for manager in cls.get_all_fig_managers():
132 if force or manager.canvas.figure.stale:
--> 133 manager.canvas.draw_idle()
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:1989, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
1987 if not self._is_idle_drawing:
1988 with self._idle_draw_cntx():
-> 1989 self.draw(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:438, in FigureCanvasAgg.draw(self)
435 # Acquire a lock on the shared font cache.
436 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
437 else nullcontext()):
--> 438 self.figure.draw(self.renderer)
439 # A GUI class may be need to update a window using this draw, so
440 # don't forget to call the superclass.
441 super().draw()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:2257, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2254 # we do this instead of `self.figure.draw_without_rendering`
2255 # so that we can inject the orientation
2256 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2257 self.figure.draw(renderer)
2258 else:
2259 renderer = None
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
<Figure size 300x600 with 2 Axes>
Fitness distance correlation (FDC) reveals more:¶
from pyxla import fdc
corr, plot = fdc(sphere_sample)
corr
WARNING:root:No D file is present, thus, computing the D file... Computing an entire D file can be time consuming. Instead, you can call the function with the keyword argument `compute_D_file` set to `False` to speed up computation, as only the required distances will be calculated.
INFO:root:D file has been loaded to the current sample and is saved to ./Sphere_D.csv
{'fdc_f0': np.float64(0.9999999999999999)}
Error in callback <function _draw_all_if_interactive at 0x78cde0056e50> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/pyplot.py:300, in _draw_all_if_interactive()
298 def _draw_all_if_interactive() -> None:
299 if matplotlib.is_interactive():
--> 300 draw_all()
File /usr/local/lib/python3.14/site-packages/matplotlib/_pylab_helpers.py:133, in Gcf.draw_all(cls, force)
131 for manager in cls.get_all_fig_managers():
132 if force or manager.canvas.figure.stale:
--> 133 manager.canvas.draw_idle()
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:1989, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
1987 if not self._is_idle_drawing:
1988 with self._idle_draw_cntx():
-> 1989 self.draw(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:438, in FigureCanvasAgg.draw(self)
435 # Acquire a lock on the shared font cache.
436 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
437 else nullcontext()):
--> 438 self.figure.draw(self.renderer)
439 # A GUI class may be need to update a window using this draw, so
440 # don't forget to call the superclass.
441 super().draw()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:2257, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2254 # we do this instead of `self.figure.draw_without_rendering`
2255 # so that we can inject the orientation
2256 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2257 self.figure.draw(renderer)
2258 else:
2259 renderer = None
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
<Figure size 300x300 with 1 Axes>
According to the output above, the sphere problem shows a high fitness-distance correlation between the objective values and distance to the nearest local minimum. This means that the search space is not deceptive, in that a search in the solution space will likely arrive at the global minimum since solutions become fitter and fitter as the search gets closer to the global minimum.
corr, plot = fdc(deceptive_sample)
corr
WARNING:root:No D file is present, thus, computing the D file... Computing an entire D file can be time consuming. Instead, you can call the function with the keyword argument `compute_D_file` set to `False` to speed up computation, as only the required distances will be calculated.
INFO:root:D file has been loaded to the current sample and is saved to ./Deceptive_D.csv
{'fdc_f0': np.float64(-0.7070987098709871)}
Error in callback <function _draw_all_if_interactive at 0x78cde0056e50> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/pyplot.py:300, in _draw_all_if_interactive()
298 def _draw_all_if_interactive() -> None:
299 if matplotlib.is_interactive():
--> 300 draw_all()
File /usr/local/lib/python3.14/site-packages/matplotlib/_pylab_helpers.py:133, in Gcf.draw_all(cls, force)
131 for manager in cls.get_all_fig_managers():
132 if force or manager.canvas.figure.stale:
--> 133 manager.canvas.draw_idle()
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:1989, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
1987 if not self._is_idle_drawing:
1988 with self._idle_draw_cntx():
-> 1989 self.draw(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:438, in FigureCanvasAgg.draw(self)
435 # Acquire a lock on the shared font cache.
436 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
437 else nullcontext()):
--> 438 self.figure.draw(self.renderer)
439 # A GUI class may be need to update a window using this draw, so
440 # don't forget to call the superclass.
441 super().draw()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:2257, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2254 # we do this instead of `self.figure.draw_without_rendering`
2255 # so that we can inject the orientation
2256 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2257 self.figure.draw(renderer)
2258 else:
2259 renderer = None
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
<Figure size 300x300 with 1 Axes>
Conversely, the output above shows a negative correlation between distance to the nearest local minimum and objective values for the deceptive problem. Therefore, as one nears the global minimum, solutions tend to deteriorate in fitness, signalling the presence of multiple local minima. In this case, pyxla.fdc() indicates that the problem is indeed deceptive.
Rank distance correlation (RDC)¶
pyxla.rdc() corrobotates pyxla.fdc() since it operates on the objective ranks rather than the values.
from pyxla import rdc
corr, plot = rdc(sphere_sample)
corr
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[6], line 3
1 from pyxla import rdc
2
----> 3 corr, plot = rdc(sphere_sample)
4 corr
File /builds/aliefooghe/pyxla/src/pyxla/__init__.py:1011, in rdc(sample, compute_D_file)
1008 d_nearest_best = min(d_nearest_best, d)
1009 RDC.loc[t_idx, "distance"] = d_nearest_best
-> 1011 sp_corr, _ = scipy.stats.spearmanr(RDC[col], RDC["distance"])
1012 corrs.update({f"rdc_{col}": sp_corr})
1014 ax = axs[i] if numR > 1 else axs
File /usr/local/lib/python3.14/site-packages/scipy/stats/_stats_py.py:5446, in spearmanr(a, b, axis, nan_policy, alternative)
5442 if constant_axis:
5443 with np.errstate(invalid='ignore'):
5444 rs = np.corrcoef(a_ranked, rowvar=axisout)
5445 else:
-> 5446 rs = np.corrcoef(a_ranked, rowvar=axisout)
5447
5448 dof = n_obs - 2 # degrees of freedom
5449
File /usr/local/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py:3028, in corrcoef(x, y, rowvar, dtype)
2910 @array_function_dispatch(_corrcoef_dispatcher)
2911 def corrcoef(x, y=None, rowvar=True, *,
2912 dtype=None):
2913 """
2914 Return Pearson product-moment correlation coefficients.
2915
(...) 3026
3027 """
-> 3028 c = cov(x, y, rowvar, dtype=dtype)
3029 try:
3030 d = diag(c)
File /usr/local/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py:2877, in cov(m, y, rowvar, bias, ddof, fweights, aweights, dtype)
2874 else:
2875 w *= aweights
-> 2877 avg, w_sum = average(X, axis=1, weights=w, returned=True)
2878 w_sum = w_sum[0]
2880 # Determine the normalization
File /usr/local/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py:607, in average(a, axis, weights, returned, keepdims)
603 avg = avg_as_array = np.multiply(a, wgt,
604 dtype=result_dtype).sum(axis, **keepdims_kw) / scl
606 if returned:
--> 607 if scl.shape != avg_as_array.shape:
608 scl = np.broadcast_to(scl, avg_as_array.shape, subok=True).copy()
609 return avg, scl
AttributeError: 'float' object has no attribute 'shape'
Error in callback <function _draw_all_if_interactive at 0x78cde0056e50> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/pyplot.py:300, in _draw_all_if_interactive()
298 def _draw_all_if_interactive() -> None:
299 if matplotlib.is_interactive():
--> 300 draw_all()
File /usr/local/lib/python3.14/site-packages/matplotlib/_pylab_helpers.py:133, in Gcf.draw_all(cls, force)
131 for manager in cls.get_all_fig_managers():
132 if force or manager.canvas.figure.stale:
--> 133 manager.canvas.draw_idle()
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:1989, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
1987 if not self._is_idle_drawing:
1988 with self._idle_draw_cntx():
-> 1989 self.draw(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:438, in FigureCanvasAgg.draw(self)
435 # Acquire a lock on the shared font cache.
436 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
437 else nullcontext()):
--> 438 self.figure.draw(self.renderer)
439 # A GUI class may be need to update a window using this draw, so
440 # don't forget to call the superclass.
441 super().draw()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:258, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
257 try:
--> 258 report = subprocess.check_output(
259 command, cwd=cwd if cwd is not None else cls._cache_dir,
260 stderr=subprocess.STDOUT)
261 except subprocess.CalledProcessError as exc:
File /usr/local/lib/python3.14/subprocess.py:473, in check_output(timeout, *popenargs, **kwargs)
471 kwargs['input'] = empty
--> 473 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
474 **kwargs).stdout
File /usr/local/lib/python3.14/subprocess.py:555, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
553 kwargs['stderr'] = PIPE
--> 555 with Popen(*popenargs, **kwargs) as process:
556 try:
File /usr/local/lib/python3.14/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /usr/local/lib/python3.14/subprocess.py:1990, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1989 if err_filename is not None:
-> 1990 raise child_exception_type(errno_num, err_msg, err_filename)
1991 else:
FileNotFoundError: [Errno 2] No such file or directory: 'latex'
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:2257, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2254 # we do this instead of `self.figure.draw_without_rendering`
2255 # so that we can inject the orientation
2256 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2257 self.figure.draw(renderer)
2258 else:
2259 renderer = None
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /usr/local/lib/python3.14/site-packages/matplotlib/figure.py:3276, in Figure.draw(self, renderer)
3274 if self.axes and self.get_layout_engine() is not None:
3275 try:
-> 3276 self.get_layout_engine().execute(self)
3277 except ValueError:
3278 pass
File /usr/local/lib/python3.14/site-packages/matplotlib/layout_engine.py:278, in ConstrainedLayoutEngine.execute(self, fig)
275 w_pad = self._params['w_pad'] / width
276 h_pad = self._params['h_pad'] / height
--> 278 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
279 wspace=self._params['wspace'],
280 hspace=self._params['hspace'],
281 rect=self._params['rect'],
282 compress=self._compress)
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:116, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
106 return
108 for _ in range(2):
109 # do the algorithm twice. This has to be done because decorations
110 # change size after the first re-position (i.e. x/yticklabels get
(...) 114 # make margins for all the Axes and subfigures in the
115 # figure. Add margins for colorbars...
--> 116 make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
117 w_pad=w_pad, hspace=hspace, wspace=wspace)
118 make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
119 w_pad=w_pad)
121 # if a layout is such that a columns (or rows) margin has no
122 # constraints, we need to make all such instances in the grid
123 # match in margin size.
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:389, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
385 return
387 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
388 hspace=hspace, wspace=wspace)
--> 389 pos, bbox = get_pos_and_bbox(ax, renderer)
390 # the margin is the distance between the bounding box of the Axes
391 # and its position (plus the padding from above)
392 margin['left'] += pos.x0 - bbox.x0
File /usr/local/lib/python3.14/site-packages/matplotlib/_constrained_layout.py:637, in get_pos_and_bbox(ax, renderer)
635 # pos is in panel co-ords, but we need in figure for the layout
636 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 637 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
638 if tightbbox is None:
639 bbox = pos
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axes/_base.py:4758, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4756 if self.axison and axis.get_visible():
4757 if for_layout_only:
-> 4758 ba = martist._get_tightbbox_for_layout_only(axis, renderer)
4759 else:
4760 ba = axis.get_tightbbox(renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/artist.py:1485, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1479 """
1480 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1481 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
1482 when encountering third-party subclasses that do not support it.
1483 """
1484 try:
-> 1485 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1486 except TypeError:
1487 return obj.get_tightbbox(*args, **kwargs)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1427, in Axis.get_tightbbox(self, renderer, for_layout_only)
1424 renderer = self.get_figure(root=True)._get_renderer()
1425 ticks_to_draw = self._update_ticks()
-> 1427 self._update_label_position(renderer)
1429 # go back to just this axis's tick labels
1430 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2615, in XAxis._update_label_position(self, renderer)
2611 return
2613 # get bounding boxes for this axis and any siblings
2614 # that have been set by `fig.align_xlabels()`
-> 2615 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
2616 x, y = self.label.get_position()
2618 if self.label_position == 'bottom':
2619 # Union with extents of the bottom spine if present, of the axes otherwise.
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:2403, in Axis._get_tick_boxes_siblings(self, renderer)
2401 axis = ax._axis_map[name]
2402 ticks_to_draw = axis._update_ticks()
-> 2403 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
2404 bboxes.extend(tlb)
2405 bboxes2.extend(tlb2)
File /usr/local/lib/python3.14/site-packages/matplotlib/axis.py:1404, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
1402 def _get_ticklabel_bboxes(self, ticks, renderer):
1403 """Return lists of bboxes for ticks' label1's and label2's."""
-> 1404 return ([tick.label1.get_window_extent(renderer)
1405 for tick in ticks
1406 if tick.label1.get_visible() and tick.label1.get_in_layout()],
1407 [tick.label2.get_window_extent(renderer)
1408 for tick in ticks
1409 if tick.label2.get_visible() and tick.label2.get_in_layout()])
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:1076, in Text.get_window_extent(self, renderer, dpi)
1071 raise RuntimeError(
1072 "Cannot get window extent of text w/o renderer. You likely "
1073 "want to call 'figure.draw_without_rendering()' first.")
1075 with cbook._setattr_cm(fig, dpi=dpi):
-> 1076 bbox, _, _ = self._get_layout(self._renderer)
1077 x, y = self.get_unitless_position()
1078 x, y = self.get_transform().transform((x, y))
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:465, in Text._get_layout(self, renderer)
462 break
463 if None in (min_ascent, min_descent):
464 # Fallback to font measurement.
--> 465 _, h, min_descent = _get_text_metrics_with_cache(
466 renderer, "lp", self._fontproperties,
467 ismath="TeX" if self.get_usetex() else False,
468 dpi=dpi)
469 min_ascent = h - min_descent
470 line_gap = 0
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:59, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
52 get_text_metrics = _get_text_metrics_function(renderer)
53 # call the function to compute the metrics and return
54 #
55 # We pass a copy of the fontprop because FontProperties is both mutable and
56 # has a `__hash__` that depends on that mutable state. This is not ideal
57 # as it means the hash of an object is not stable over time which leads to
58 # very confusing behavior when used as keys in dictionaries or hashes.
---> 59 return get_text_metrics(text, fontprop.copy(), ismath, dpi)
File /usr/local/lib/python3.14/site-packages/matplotlib/text.py:125, in _get_text_metrics_function.<locals>._text_metrics(text, fontprop, ismath, dpi)
120 raise RuntimeError(
121 "Trying to get text metrics for a renderer that no longer exists. "
122 "This should never happen and is evidence of a bug elsewhere."
123 )
124 # do the actual method call we need and return the result
--> 125 return local_renderer.get_text_width_height_descent(text, fontprop, ismath)
File /usr/local/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:256, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
254 _api.check_in_list(["TeX", True, False], ismath=ismath)
255 if ismath == "TeX":
--> 256 return super().get_text_width_height_descent(s, prop, ismath)
258 if ismath:
259 parse = self.mathtext_parser.parse(s, self.dpi, prop)
File /usr/local/lib/python3.14/site-packages/matplotlib/backend_bases.py:589, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
585 fontsize = prop.get_size_in_points()
587 if ismath == 'TeX':
588 # todo: handle properties
--> 589 return self.get_texmanager().get_text_width_height_descent(
590 s, fontsize, renderer=self)
592 dpi = self.points_to_pixels(72)
593 if ismath:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:369, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
367 if tex.strip() == '':
368 return 0, 0, 0
--> 369 dvipath = cls.make_dvi(tex, fontsize)
370 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
371 with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:301, in TexManager.make_dvi(cls, tex, fontsize)
298 with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
299 Path(tmpdir, "file.tex").write_text(
300 cls._get_tex_source(tex, fontsize), encoding='utf-8')
--> 301 cls._run_checked_subprocess(
302 ["latex", "-interaction=nonstopmode", "-halt-on-error",
303 "-no-shell-escape", "file.tex"], tex, cwd=tmpdir)
304 Path(tmpdir, "file.dvi").replace(dvipath)
305 # Also move the tex source to the main cache directory, but
306 # only for backcompat.
File /usr/local/lib/python3.14/site-packages/matplotlib/texmanager.py:274, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
262 raise RuntimeError(
263 '{prog} was not able to process the following string:\n'
264 '{tex!r}\n\n'
(...) 271 exc=exc.output.decode('utf-8', 'backslashreplace'))
272 ) from None
273 except (FileNotFoundError, OSError) as exc:
--> 274 raise RuntimeError(
275 f'Failed to process string with tex because {command[0]} '
276 'could not be found') from exc
277 _log.debug(report)
278 return report
RuntimeError: Failed to process string with tex because latex could not be found
<Figure size 900x300 with 3 Axes>
corr, plot = rdc(deceptive_sample)
corr
{'rdc_f0': np.float64(-0.597095709570957)}
Pairwise distance correlation (PDC)¶
from pyxla import pdc
corr, plot = pdc(sphere_sample)
corr
{'pdc_F': np.float64(0.4387542029401414),
'pdc_f0-rank': np.float64(0.34382468358143525)}
pyxla.pdc() shows that for the sphere function, there is low correlation between pairwise distance on the solution space and pairwise distance on the objective space. This shows that the sphere function is not monotonic.
corr, plot = pdc(deceptive_sample)
corr
{'pdc_F': np.float64(0.6247890687938944),
'pdc_f0-rank': np.float64(0.6685896526930889)}
Similarly the deceptive function it not monotonic and appears more rugged that the sphere function.
Neighbouring solutions’ objective values (fitness) correlation (NFC)¶
from pyxla import nfc
corr, plot = nfc(sphere_sample)
corr
{'nfc_all_X_for_f0': np.float64(0.9972665429808286)}
The constrained sphere problem is found to have high evolvability, evidenced by a high NFC value. This is expected, since the sphere function is one of the simplest continuous optimisation problems.
corr, plot = nfc(deceptive_sample)
corr
{'nfc_all_X_for_f0': np.float64(0.9265182436611007)}
The deceptive problem has a high NFC but a lower value that the sphere function as expected, since the sphere problem is an easier problem.
Neighbouring solutions’ ranks correlation (NRC)¶
pyxla.nrc() corroborates pyxla.nfc() since it is based on the objective ranks.
from pyxla import nrc
corr, plot = nrc(sphere_sample)
corr
{'NRC_for_f0_ranks': '0.9973'}
corr, plot = nrc(deceptive_sample)
corr
{'NRC_for_f0_ranks': '0.9265'}
Dispersion of best solution (disp_best)¶
pyxla.disp_best() can tell if the problem has a global structure or whether it has many funnels.
from pyxla import disp_best
corr, plot = disp_best(sphere_sample)
corr
corr, plot = disp_best(deceptive_sample)
corr
The sphere problem’s objective has a negative dispersion metric value which indicates the presence of a global structure, as expected. The deceptive problem, on the other hand, has a positive dispersion metric value, indicating the presence of funnels. The scatter plots visually express the dispersion, where for the constrained sphere problem, the spread of pairwise distances grows as the sample size of the best solution is increased. Conversely, for the deceptive problem, the gaps between the clusters of points for lower sample sizes show that indeed the best solutions are much further apart, accounting for the lack of a global structure.