Skip to content

fix: show units on curve, line and scatter axis labels#963

Merged
blooop merged 2 commits into
mainfrom
fix/axis-units-curve-line-scatter
Jun 13, 2026
Merged

fix: show units on curve, line and scatter axis labels#963
blooop merged 2 commits into
mainfrom
fix/axis-units-curve-line-scatter

Conversation

@blooop

@blooop blooop commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #960, as promised in this comment: the audit found that curve_result.py, line_result.py and scatter_result.py were the remaining plots that didn't show units on their axes (they set no axis label at all).

  • Adds a shared label_with_units() helper in bencher.utils producing name [units], following the existing 'ul' = unitless convention from sweep_base.describe_variable
  • Applies it to:
    • HoloviewResult._build_curve_overlay — covers to_curve and the aggregated line/over-time path (x = float input var, y = result var)
    • LineResult.to_line_ds (float-x path and 0D over_time path) and _to_line_tap_ds
    • ScatterResult._to_scatter_ds
  • Labels are applied with kwargs.setdefault, so explicit user xlabel/ylabel kwargs still take precedence

Test plan

  • New test/test_axis_units.py: asserts distance [m] / throughput [ops/s] on curve and line axes, score [m] on scatter, and unit tests for label_with_units (units / no units / 'ul')
  • Full suite: 1485 passed, 5 skipped; ruff + pylint clean

🤖 Generated with Claude Code

Summary by Sourcery

Add shared axis labeling helper and ensure curve, line, and scatter plots display variable units on their axes.

New Features:

  • Introduce a reusable label_with_units helper to generate axis labels from parameter names and units.

Enhancements:

  • Apply unit-aware axis labels to curve, line, and scatter Holoviews plots while preserving user-provided labels.

Tests:

  • Add axis unit tests for curve, line, and scatter plots, along with unit tests for the label_with_units helper.

Follow-up to #960: histogram gained units there and band/bar/heatmap/
surface/distribution already showed them. This closes the remaining gaps
flagged in the audit — curve_result.py, line_result.py and
scatter_result.py set no axis labels at all.

Adds a shared label_with_units() helper in bencher.utils that follows
the existing 'ul' = unitless convention from sweep_base, and applies it:
- _build_curve_overlay (covers to_curve and the aggregated line path)
- to_line_ds (float-x path, 0D over_time path) and _to_line_tap_ds
- _to_scatter_ds

Labels are applied with kwargs.setdefault so explicit user xlabel/ylabel
kwargs still win.
@sourcery-ai

sourcery-ai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds a shared label_with_units() helper and uses it to apply unit-aware axis labels to curve, line, and scatter plots, while preserving user-specified labels and adding tests to verify behavior.

File-Level Changes

Change Details Files
Introduce reusable helper for axis labels that include units and handle unitless variables
  • Add label_with_units(var) to construct 'name [units]' labels, omitting units when empty or 'ul'
  • Use getattr(var, 'units', '') to tolerate parameter-like objects without a units attribute
  • Document helper behavior and align it with existing unitless ('ul') convention from sweep_base.describe_variable
bencher/utils.py
Apply unit-aware labels to line plots while respecting explicit user-provided labels
  • Set default ylabel for over_time line plots based on result_var via label_with_units
  • Set default xlabel and ylabel for float-x line plots using the configured float input var and result_var
  • Apply the same axis-label defaults to tap-enabled line plots in _to_line_tap_ds, using kwargs.setdefault so explicit xlabel/ylabel overrides are honored
bencher/results/holoview_results/line_result.py
Apply unit-aware axis labels to curve overlays in HoloviewResult
  • Set default ylabel for curve overlays using label_with_units(result_var)
  • Resolve the x-axis float variable by matching kdims[0] against plt_cnt_cfg.float_vars and set default xlabel via label_with_units when found
  • Ensure all label defaults are applied via kwargs.setdefault to avoid overriding user-specified labels
bencher/results/holoview_results/holoview_result.py
Apply unit-aware axis labels to scatter plots and clean up method signature
  • Remove the unused-argument pylint suppression comment now that kwargs is used
  • Set default ylabel for scatter plots from the result_var via label_with_units
  • Set default xlabel from the first input variable, when present, using label_with_units, while still allowing user-provided labels to override
bencher/results/holoview_results/scatter_result.py
Add tests covering axis labels with units across curve, line, and scatter plots plus the helper function
  • Introduce helper functions _unwrap_hv and _find_element to locate underlying holoviews elements in panel/hv structures
  • Define FloatBench and CatBench benchmark classes to generate line/curve and scatter plots with controlled units
  • Add _LabelBench to provide parameters for unit-label helper tests (with units, no units, 'ul')
  • Add TestLabelWithUnits to validate label_with_units behavior for units, no units, and unitless convention
  • Add TestCurveAxisUnits, TestLineAxisUnits, and TestScatterAxisUnits to assert expected xlabel/ylabel values on hv.Curve and hv.Scatter elements, including the 'ul' behavior for StringSweep
test/test_axis_units.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions

Copy link
Copy Markdown

Performance Report for c2a9e4b

Metric Value
Total tests 1665
Total time 127.33s
Mean 0.0765s
Median 0.0020s
Top 10 slowest tests
Test Time (s)
test.test_bench_examples.TestBenchExamples::test_example_meta 18.373
test.test_over_time_save_perf::test_save_faster_without_aggregated_tab 5.590
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_drift.py] 4.649
test.test_generated_examples::test_generated_example[cartesian_animation/example_cartesian_animation.py] 3.255
test.test_split_render_examples::test_split_render_subprocess_media 3.196
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_step.py] 2.915
test.test_hash_persistent.TestCrossProcessDeterminism::test_hash_stable_across_two_processes[ResultBool] 2.861
test.test_generated_examples::test_generated_example[result_types/result_image/example_result_image_to_video.py] 2.856
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_noise.py] 2.834
test.test_over_time_repeats.TestMaxSliderPoints::test_default_subsampling_caps_at_max 2.454

Full report

Updated by Performance Tracking workflow

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • In LineResult.to_line_ds and _to_line_tap_ds, accessing self.plt_cnt_cfg.float_vars[0] assumes at least one float var is present; consider guarding this or mirroring the safer lookup-by-name pattern used in _build_curve_overlay to avoid potential IndexError in edge configurations.
  • The new label_with_units helper assumes the presence of a .name attribute and a string-like .units; if this might be reused more broadly, consider adding a fallback (e.g., getattr(var, "name", str(var))) to make it more robust to non-parameter inputs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `LineResult.to_line_ds` and `_to_line_tap_ds`, accessing `self.plt_cnt_cfg.float_vars[0]` assumes at least one float var is present; consider guarding this or mirroring the safer lookup-by-name pattern used in `_build_curve_overlay` to avoid potential `IndexError` in edge configurations.
- The new `label_with_units` helper assumes the presence of a `.name` attribute and a string-like `.units`; if this might be reused more broadly, consider adding a fallback (e.g., `getattr(var, "name", str(var))`) to make it more robust to non-parameter inputs.

## Individual Comments

### Comment 1
<location path="test/test_axis_units.py" line_range="96-106" />
<code_context>
+        self.assertEqual(label_with_units(_LabelBench.param.unitless), "unitless")
+
+
+class TestCurveAxisUnits(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        cls.res = _run_sweep(FloatBench, "units_curve", ["distance"], ["throughput"], repeats=2)
+
+    def test_curve_axis_labels_show_units(self):
+        curve = _find_element(self.res.to_curve(), hv.Curve)
+        self.assertIsNotNone(curve)
+        opts = curve.opts.get().kwargs
+        self.assertEqual(opts["xlabel"], "distance [m]")
+        self.assertEqual(opts["ylabel"], "throughput [ops/s]")
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test to verify that explicit xlabel/ylabel kwargs override the auto-generated labels.

Since the tests only cover auto-populated labels, please also add a case calling `self.res.to_curve(xlabel="custom x", ylabel="custom y")` and asserting those values are preserved. This will lock in the precedence behavior of explicit labels over `label_with_units` and guard against future regressions.

```suggestion
class TestCurveAxisUnits(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.res = _run_sweep(FloatBench, "units_curve", ["distance"], ["throughput"], repeats=2)

    def test_curve_axis_labels_show_units(self):
        curve = _find_element(self.res.to_curve(), hv.Curve)
        self.assertIsNotNone(curve)
        opts = curve.opts.get().kwargs
        self.assertEqual(opts["xlabel"], "distance [m]")
        self.assertEqual(opts["ylabel"], "throughput [ops/s]")

    def test_explicit_axis_labels_override_units(self):
        curve = _find_element(
            self.res.to_curve(xlabel="custom x", ylabel="custom y"),
            hv.Curve,
        )
        self.assertIsNotNone(curve)
        opts = curve.opts.get().kwargs
        self.assertEqual(opts["xlabel"], "custom x")
        self.assertEqual(opts["ylabel"], "custom y")
```
</issue_to_address>

### Comment 2
<location path="test/test_axis_units.py" line_range="109-119" />
<code_context>
+        self.assertEqual(opts["ylabel"], "throughput [ops/s]")
+
+
+class TestLineAxisUnits(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        cls.res = _run_sweep(FloatBench, "units_line", ["distance"], ["throughput"], repeats=1)
+
+    def test_line_axis_labels_show_units(self):
+        curve = _find_element(self.res.to_line(use_tap=False), hv.Curve)
+        self.assertIsNotNone(curve)
+        opts = curve.opts.get().kwargs
+        self.assertEqual(opts["xlabel"], "distance [m]")
+        self.assertEqual(opts["ylabel"], "throughput [ops/s]")
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add coverage for the tap-based line path (use_tap=True) to exercise `_to_line_tap_ds`.

The current test only covers `to_line(use_tap=False)` (float-x path), but this PR also adds labeling in `_to_line_tap_ds`. Please add another test or parametrize this one to also call `self.res.to_line(use_tap=True)` and assert the same xlabel/ylabel values, so the tap-based path is exercised and its axis units remain covered.

```suggestion
class TestLineAxisUnits(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.res = _run_sweep(FloatBench, "units_line", ["distance"], ["throughput"], repeats=1)

    def _assert_line_axis_labels(self, curve):
        self.assertIsNotNone(curve)
        opts = curve.opts.get().kwargs
        self.assertEqual(opts["xlabel"], "distance [m]")
        self.assertEqual(opts["ylabel"], "throughput [ops/s]")

    def test_line_axis_labels_show_units_float(self):
        curve = _find_element(self.res.to_line(use_tap=False), hv.Curve)
        self._assert_line_axis_labels(curve)

    def test_line_axis_labels_show_units_tap(self):
        curve = _find_element(self.res.to_line(use_tap=True), hv.Curve)
        self._assert_line_axis_labels(curve)
```
</issue_to_address>

### Comment 3
<location path="test/test_axis_units.py" line_range="84-93" />
<code_context>
+    unitless = bn.ResultFloat(units="ul")
+
+
+class TestLabelWithUnits(unittest.TestCase):
+    def test_name_and_units(self):
+        self.assertEqual(label_with_units(_LabelBench.param.with_units), "with_units [ms]")
+
+    def test_no_units(self):
+        self.assertEqual(label_with_units(_LabelBench.param.no_units), "no_units")
+
+    def test_unitless_convention(self):
+        """'ul' is the sweep-variable convention for unitless and must not be shown."""
+        self.assertEqual(label_with_units(_LabelBench.param.unitless), "unitless")
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add a label_with_units test for objects without a `units` attribute and for `units=None`.

To fully cover the `getattr(var, "units", "")` behavior, please add tests for (1) an object with only a `name` attribute and no `units`, and (2) a result var with `units=None`. Both should yield just the name, confirming correct handling of non-param objects and `None` units.

Suggested implementation:

```python
class _LabelBench(bn.ParametrizedSweep):
    """Params must be class-bound for param to assign their names."""

    with_units = bn.ResultFloat(units="ms")
    no_units = bn.ResultFloat(units="")
    unitless = bn.ResultFloat(units="ul")
    none_units = bn.ResultFloat(units=None)

```

```python
class TestLabelWithUnits(unittest.TestCase):
    def test_name_and_units(self):
        self.assertEqual(label_with_units(_LabelBench.param.with_units), "with_units [ms]")

    def test_no_units(self):
        self.assertEqual(label_with_units(_LabelBench.param.no_units), "no_units")

    def test_unitless_convention(self):
        """'ul' is the sweep-variable convention for unitless and must not be shown."""
        self.assertEqual(label_with_units(_LabelBench.param.unitless), "unitless")

    def test_object_without_units_attribute(self):
        class Dummy:
            name = "without_units"

        self.assertEqual(label_with_units(Dummy()), "without_units")

    def test_none_units(self):
        """Result vars with units=None should also yield just the name."""
        self.assertEqual(label_with_units(_LabelBench.param.none_units), "none_units")

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread test/test_axis_units.py
Comment on lines +96 to +106
class TestCurveAxisUnits(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.res = _run_sweep(FloatBench, "units_curve", ["distance"], ["throughput"], repeats=2)

def test_curve_axis_labels_show_units(self):
curve = _find_element(self.res.to_curve(), hv.Curve)
self.assertIsNotNone(curve)
opts = curve.opts.get().kwargs
self.assertEqual(opts["xlabel"], "distance [m]")
self.assertEqual(opts["ylabel"], "throughput [ops/s]")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a test to verify that explicit xlabel/ylabel kwargs override the auto-generated labels.

Since the tests only cover auto-populated labels, please also add a case calling self.res.to_curve(xlabel="custom x", ylabel="custom y") and asserting those values are preserved. This will lock in the precedence behavior of explicit labels over label_with_units and guard against future regressions.

Suggested change
class TestCurveAxisUnits(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.res = _run_sweep(FloatBench, "units_curve", ["distance"], ["throughput"], repeats=2)
def test_curve_axis_labels_show_units(self):
curve = _find_element(self.res.to_curve(), hv.Curve)
self.assertIsNotNone(curve)
opts = curve.opts.get().kwargs
self.assertEqual(opts["xlabel"], "distance [m]")
self.assertEqual(opts["ylabel"], "throughput [ops/s]")
class TestCurveAxisUnits(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.res = _run_sweep(FloatBench, "units_curve", ["distance"], ["throughput"], repeats=2)
def test_curve_axis_labels_show_units(self):
curve = _find_element(self.res.to_curve(), hv.Curve)
self.assertIsNotNone(curve)
opts = curve.opts.get().kwargs
self.assertEqual(opts["xlabel"], "distance [m]")
self.assertEqual(opts["ylabel"], "throughput [ops/s]")
def test_explicit_axis_labels_override_units(self):
curve = _find_element(
self.res.to_curve(xlabel="custom x", ylabel="custom y"),
hv.Curve,
)
self.assertIsNotNone(curve)
opts = curve.opts.get().kwargs
self.assertEqual(opts["xlabel"], "custom x")
self.assertEqual(opts["ylabel"], "custom y")

Comment thread test/test_axis_units.py
Comment on lines +109 to +119
class TestLineAxisUnits(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.res = _run_sweep(FloatBench, "units_line", ["distance"], ["throughput"], repeats=1)

def test_line_axis_labels_show_units(self):
curve = _find_element(self.res.to_line(use_tap=False), hv.Curve)
self.assertIsNotNone(curve)
opts = curve.opts.get().kwargs
self.assertEqual(opts["xlabel"], "distance [m]")
self.assertEqual(opts["ylabel"], "throughput [ops/s]")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add coverage for the tap-based line path (use_tap=True) to exercise _to_line_tap_ds.

The current test only covers to_line(use_tap=False) (float-x path), but this PR also adds labeling in _to_line_tap_ds. Please add another test or parametrize this one to also call self.res.to_line(use_tap=True) and assert the same xlabel/ylabel values, so the tap-based path is exercised and its axis units remain covered.

Suggested change
class TestLineAxisUnits(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.res = _run_sweep(FloatBench, "units_line", ["distance"], ["throughput"], repeats=1)
def test_line_axis_labels_show_units(self):
curve = _find_element(self.res.to_line(use_tap=False), hv.Curve)
self.assertIsNotNone(curve)
opts = curve.opts.get().kwargs
self.assertEqual(opts["xlabel"], "distance [m]")
self.assertEqual(opts["ylabel"], "throughput [ops/s]")
class TestLineAxisUnits(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.res = _run_sweep(FloatBench, "units_line", ["distance"], ["throughput"], repeats=1)
def _assert_line_axis_labels(self, curve):
self.assertIsNotNone(curve)
opts = curve.opts.get().kwargs
self.assertEqual(opts["xlabel"], "distance [m]")
self.assertEqual(opts["ylabel"], "throughput [ops/s]")
def test_line_axis_labels_show_units_float(self):
curve = _find_element(self.res.to_line(use_tap=False), hv.Curve)
self._assert_line_axis_labels(curve)
def test_line_axis_labels_show_units_tap(self):
curve = _find_element(self.res.to_line(use_tap=True), hv.Curve)
self._assert_line_axis_labels(curve)

Comment thread test/test_axis_units.py
Comment on lines +84 to +93
class TestLabelWithUnits(unittest.TestCase):
def test_name_and_units(self):
self.assertEqual(label_with_units(_LabelBench.param.with_units), "with_units [ms]")

def test_no_units(self):
self.assertEqual(label_with_units(_LabelBench.param.no_units), "no_units")

def test_unitless_convention(self):
"""'ul' is the sweep-variable convention for unitless and must not be shown."""
self.assertEqual(label_with_units(_LabelBench.param.unitless), "unitless")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a label_with_units test for objects without a units attribute and for units=None.

To fully cover the getattr(var, "units", "") behavior, please add tests for (1) an object with only a name attribute and no units, and (2) a result var with units=None. Both should yield just the name, confirming correct handling of non-param objects and None units.

Suggested implementation:

class _LabelBench(bn.ParametrizedSweep):
    """Params must be class-bound for param to assign their names."""

    with_units = bn.ResultFloat(units="ms")
    no_units = bn.ResultFloat(units="")
    unitless = bn.ResultFloat(units="ul")
    none_units = bn.ResultFloat(units=None)
class TestLabelWithUnits(unittest.TestCase):
    def test_name_and_units(self):
        self.assertEqual(label_with_units(_LabelBench.param.with_units), "with_units [ms]")

    def test_no_units(self):
        self.assertEqual(label_with_units(_LabelBench.param.no_units), "no_units")

    def test_unitless_convention(self):
        """'ul' is the sweep-variable convention for unitless and must not be shown."""
        self.assertEqual(label_with_units(_LabelBench.param.unitless), "unitless")

    def test_object_without_units_attribute(self):
        class Dummy:
            name = "without_units"

        self.assertEqual(label_with_units(Dummy()), "without_units")

    def test_none_units(self):
        """Result vars with units=None should also yield just the name."""
        self.assertEqual(label_with_units(_LabelBench.param.none_units), "none_units")

Address Sourcery review on #963:
- Exercise _to_line_tap_ds via to_line(use_tap=True), asserting the same
  xlabel/ylabel units as the float-x path
- Add label_with_units tests for objects with no units attribute and units=None
@blooop

blooop commented Jun 13, 2026

Copy link
Copy Markdown
Owner Author

Addressed the Sourcery review in a08c472:

  • Tap-based line path coverage — added test_line_tap_axis_labels_show_units exercising to_line(use_tap=True) (_to_line_tap_ds), asserting the same distance [m] / throughput [ops/s] labels via a shared _assert_line_axis_labels helper.
  • label_with_units edge cases — added test_no_units_attribute (object with only name, exercising the getattr(var, "units", "") fallback) and test_units_none (units=None), both yielding the bare name.

On the two non-blocking suggestions, no change made:

  • float_vars[0] IndexErrorto_line_ds already guards with an early return None when not self.plt_cnt_cfg.float_vars (line 139), and in _to_line_tap_ds the x = float_vars[0].name access is pre-existing; this PR only adds the label line, so it introduces no new index risk. Out of scope to refactor here.
  • .name fallback in label_with_units — all callers pass param-like objects that always have .name; keeping the helper strict avoids masking a genuine misuse.

@github-actions

Copy link
Copy Markdown

Performance Report for a08c472

Metric Value
Total tests 1668
Total time 121.61s
Mean 0.0729s
Median 0.0020s
Top 10 slowest tests
Test Time (s)
test.test_bench_examples.TestBenchExamples::test_example_meta 17.362
test.test_over_time_save_perf::test_save_faster_without_aggregated_tab 4.622
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_drift.py] 4.336
test.test_split_render_examples::test_split_render_subprocess_media 3.071
test.test_generated_examples::test_generated_example[cartesian_animation/example_cartesian_animation.py] 3.032
test.test_hash_persistent.TestCrossProcessDeterminism::test_hash_stable_across_two_processes[ResultBool] 2.917
test.test_over_time_repeats.TestMaxSliderPoints::test_default_subsampling_caps_at_max 2.770
test.test_generated_examples::test_generated_example[result_types/result_image/example_result_image_to_video.py] 2.709
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_noise.py] 2.589
test.test_generated_examples::test_generated_example[regression/example_regression_tuning_step.py] 2.256

Full report

Updated by Performance Tracking workflow

@blooop blooop merged commit dfc20a6 into main Jun 13, 2026
8 checks passed
@blooop blooop deleted the fix/axis-units-curve-line-scatter branch June 13, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant