Skip to content

Conversation

@nochinxx
Copy link

@nochinxx nochinxx commented Dec 6, 2025

This PR is a first step toward refactoring the autoshape helpers to use the new layout.shape.label API in Plotly.js, while keeping backward-compatible annotation behavior for now.

Scope

This PR updates:

  • Figure.add_vline
  • Figure.add_hline
  • Figure.add_vrect
  • Figure.add_hrect

Key changes:

  1. Legacy → label shim

    • Introduce _coerce_shape_label_from_legacy_annotation_kwargs(kwargs) to translate a safe subset of annotation_* kwargs into a label dict:
      • annotation_textlabel.text
      • annotation_fontlabel.font
      • annotation_textanglelabel.textangle
    • The shim is called from each of the four helpers and is non-destructive: it does not remove annotation_* from kwargs.
    • When any annotation_* field is used, a FutureWarning is emitted to encourage migrating to label={...}.
  2. Add shape.label for autoshapes

    In _process_multiple_axis_spanning_shapes, for shape_type in:

    • "vline"
    • "hline"
    • "vrect"
    • "hrect"

    we now:

    • Split kwargs into shape_kwargs and legacy_ann via shapeannotation.split_dict_by_key_prefix(..., "annotation_").
    • Build a label_dict starting from any explicit label passed by the user and then merging in legacy fields if they are not present.
    • Attach label_dict to the new shape (shape_to_add["label"] = label_dict) before calling add_shape(...).
  3. Mapping annotation_position → label.textposition

    We partially map annotation_position into label.textposition to keep intuitive placement:

    • For lines:

      • vline:
        • "top""end"
        • "bottom""start"
        • "middle"/"center""middle"
      • hline:
        • "right""end"
        • "left""start"
        • "middle"/"center""middle"
      • A helper _normalize_legacy_line_position_to_textposition is used to validate legacy strings and to keep behavior predictable.
    • For rectangles (vrect, hrect):

      • We strip "inside " / "outside " and map the remaining part to a valid rect textposition:
        • "top left", "top center", "top right", …
        • "middle left", "middle center", "middle right", …
        • "bottom left", "bottom center", "bottom right", …
      • Single-side positions like "top", "bottom", "left", "right" are mapped to sensible defaults (e.g. "top""top center").
  4. Warnings for unsupported styling

    • annotation_bgcolor / annotation_bordercolor are not supported on shape.label and are currently ignored with a FutureWarning suggesting use of label font/color or a background shape instead.
  5. Backward compatibility (important)

    • The existing annotation path is still active:
      • axis_spanning_shape_annotation(...) is still called.
      • add_annotation(...) is still called when augmented_annotation is not None.
    • This means that:
      • existing user code that relies on layout.annotations continues to work,
      • existing tests that assert on annotations continue to pass,
      • but shapes now also carry a label, which will allow us to stop creating separate annotations in a later step.

Bug / motivation

This work is motivated by the issue where using add_vline with annotation_text on a datetime x-axis can raise a TypeError due to arithmetic on mixed types when positioning the annotation (see the discussion in #3065).

By moving toward shape.label:

  • we can avoid doing arithmetic on the coordinate values just to place the label, and
  • we get a more direct and robust representation of labels attached to shapes.

For now, we keep the annotation logic in place to avoid breaking existing behavior while we gather feedback.

Tests

Locally, I ran:

python -m pytest -q tests/test_optional/test_autoshapes/test_annotated_shapes.py

## Code PR

- [ x] I have read through the [contributing notes](https://github.com/plotly/plotly.py/blob/main/CONTRIBUTING.md) and understand the structure of the package. In particular, if my PR modifies code of `plotly.graph_objects`, my modifications concern the code generator and *not* the generated files.
- [ ] I have added tests or modified existing tests.
- [ ] For a new feature, I have added documentation examples (please see the doc checklist as well).
- [ ] I have added a CHANGELOG entry if changing anything substantial.
- [ ] For a new feature or a change in behavior, I have updated the relevant docstrings in the code.

nochinxx and others added 17 commits November 17, 2025 13:27
…el_from_legacy_annotation_kwargs(kwargs) to format kwargs into shape.label
…position normalizer

-refactor(vline): emit a single labeled shape; map legacy annotation_position to label.textposition
Fixes error in vline related to shape label instead of annotations
…notation positions to the shape’s label.textposition.
Migrate add_hrect from annotation to shape/label
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.

4 participants