@@ -74,6 +74,9 @@ class Figure(anywidget.AnyWidget):
7474 event_json = traitlets .Unicode ("{}" ).tag (sync = True )
7575 # When True the JS renderer shows a per-panel FPS / frame-time overlay.
7676 display_stats = traitlets .Bool (False ).tag (sync = True )
77+ # Figure-level help text shown in a '?' badge overlay in JS.
78+ # Empty string means no badge. Gated by apl.show_help at the Python level.
79+ help_text = traitlets .Unicode ("" ).tag (sync = True )
7780 _esm = _ESM_SOURCE
7881 # Static CSS injected by anywidget alongside _esm.
7982 # .apl-scale-wrap — outer container; width:100% means it always fills
@@ -111,7 +114,7 @@ class Figure(anywidget.AnyWidget):
111114 def __init__ (self , nrows = 1 , ncols = 1 , figsize = (640 , 480 ),
112115 width_ratios = None , height_ratios = None ,
113116 sharex = False , sharey = False ,
114- display_stats = False , ** kwargs ):
117+ display_stats = False , help = "" , ** kwargs ):
115118 super ().__init__ (** kwargs )
116119 self ._nrows = nrows
117120 self ._ncols = ncols
@@ -125,8 +128,37 @@ def __init__(self, nrows=1, ncols=1, figsize=(640, 480),
125128 self .fig_width = figsize [0 ]
126129 self .fig_height = figsize [1 ]
127130 self .display_stats = display_stats
131+ self .help_text = self ._resolve_help (help )
128132 self ._push_layout ()
129133
134+ @staticmethod
135+ def _resolve_help (text : str ) -> str :
136+ """Return *text* if ``apl.show_help`` is True (default), else ``""``."""
137+ try :
138+ import anyplotlib as _apl
139+ if not getattr (_apl , "show_help" , True ):
140+ return ""
141+ except ImportError :
142+ pass
143+ return text or ""
144+
145+ def set_help (self , text : str ) -> None :
146+ """Set (or clear) the figure-level help text shown in the **?** badge.
147+
148+ Parameters
149+ ----------
150+ text : str
151+ Help string displayed when the user clicks the **?** badge.
152+ Pass an empty string (or ``""`` ) to remove the badge entirely.
153+ Newlines (``\\ n``) are respected in the card.
154+
155+ Examples
156+ --------
157+ >>> fig.set_help("Drag peak: move μ/A\\ nPress f: least-squares fit")
158+ >>> fig.set_help("") # hide the badge
159+ """
160+ self .help_text = self ._resolve_help (text )
161+
130162 # ── subplot creation ──────────────────────────────────────────────────────
131163 def add_subplot (self , spec ) -> Axes :
132164 """Add a subplot cell and return its :class:`Axes`.
@@ -347,7 +379,8 @@ def subplots(nrows=1, ncols=1, *,
347379 width_ratios = None ,
348380 height_ratios = None ,
349381 gridspec_kw = None ,
350- display_stats = False ):
382+ display_stats = False ,
383+ help = "" ):
351384 """Create a :class:`Figure` and a grid of :class:`~anyplotlib.figure_plots.Axes`.
352385
353386 Mirrors :func:`matplotlib.pyplot.subplots`.
@@ -369,6 +402,13 @@ def subplots(nrows=1, ncols=1, *,
369402 gridspec_kw : dict, optional
370403 Extra keyword arguments forwarded to :class:`GridSpec`.
371404 Recognised keys: ``width_ratios``, ``height_ratios``.
405+ display_stats : bool, optional
406+ Show per-panel FPS / frame-time overlay. Default False.
407+ help : str, optional
408+ Help text shown when the user clicks the **?** badge on the figure.
409+ Newlines (``\\ n``) create separate lines in the card. The badge is
410+ hidden when *help* is empty (default). Suppressed globally when
411+ ``apl.show_help = False``.
372412
373413 Returns
374414 -------
@@ -398,6 +438,7 @@ def subplots(nrows=1, ncols=1, *,
398438 width_ratios = width_ratios , height_ratios = height_ratios ,
399439 sharex = sharex , sharey = sharey ,
400440 display_stats = display_stats ,
441+ help = help ,
401442 )
402443 # Build the GridSpec from the Figure's own stored ratios so there is
403444 # exactly one source of truth.
0 commit comments