@@ -379,6 +379,80 @@ def _axis_spanning_shapes_docstr(shape_type):
379379 except for x0, x1, y0, y1 or type."""
380380 return docstr
381381
382+ # helper to centralize translation of legacy annotation_* kwargs into a shape.label dict and emit a deprecation warning
383+ def _coerce_shape_label_from_legacy_annotation_kwargs (kwargs ):
384+ """
385+ Translate legacy add_*line/add_*rect annotation_* kwargs into a shape.label dict.
386+
387+ Behavior:
388+ - Pop any annotation_* keys from kwargs.
389+ - Merge them into kwargs["label"] WITHOUT overwriting explicit user-provided
390+ label fields.
391+ - Emit a FutureWarning if any legacy keys were used.
392+
393+ Args:
394+ kwargs (dict): keyword arguments passed to add_vline/add_hline/... methods.
395+
396+ Returns:
397+ dict: The same kwargs object, modified in place and also returned.
398+ """
399+ import warnings
400+
401+ legacy_used = False
402+ label = kwargs .get ("label" ) or {}
403+
404+ # 1) Text
405+ if "annotation_text" in kwargs :
406+ legacy_used = True
407+ label .setdefault ("text" , kwargs .pop ("annotation_text" ))
408+
409+ # 2) Font (expects a dict like {"family":..., "size":..., "color":...})
410+ if "annotation_font" in kwargs :
411+ legacy_used = True
412+ label .setdefault ("font" , kwargs .pop ("annotation_font" ))
413+
414+ # 3) Background/border around the text
415+ if "annotation_bgcolor" in kwargs :
416+ legacy_used = True
417+ label .setdefault ("bgcolor" , kwargs .pop ("annotation_bgcolor" ))
418+ if "annotation_bordercolor" in kwargs :
419+ legacy_used = True
420+ label .setdefault ("bordercolor" , kwargs .pop ("annotation_bordercolor" ))
421+
422+ # 4) Angle
423+ if "annotation_textangle" in kwargs :
424+ legacy_used = True
425+ label .setdefault ("textangle" , kwargs .pop ("annotation_textangle" ))
426+
427+ # 5) Position hint from the old API.
428+ # NOTE: We store this temporarily as "position" and will translate it
429+ # to concrete fields (textposition/xanchor/yanchor) in Step 3 when we
430+ # know the shape type (line vs rect) and orientation (v vs h).
431+ if "annotation_position" in kwargs :
432+ legacy_used = True
433+ pos = kwargs .pop ("annotation_position" )
434+ label .setdefault ("position" , pos )
435+
436+ # Merge collected label fields back into kwargs["label"] non-destructively
437+ if label :
438+ if "label" in kwargs and isinstance (kwargs ["label" ], dict ):
439+ merged = kwargs ["label" ].copy ()
440+ for k , v in label .items ():
441+ merged .setdefault (k , v )
442+ kwargs ["label" ] = merged
443+ else :
444+ kwargs ["label" ] = label
445+
446+ if legacy_used :
447+ warnings .warn (
448+ "annotation_* kwargs are deprecated; use label={...} to leverage Plotly.js shape labels." ,
449+ FutureWarning ,
450+ )
451+
452+ return kwargs
453+
454+
455+
382456
383457def _generator (i ):
384458 """ "cast" an iterator to a generator"""
0 commit comments