Repository: matplotlib/matplotlib
File: lib/matplotlib/widgets.py (Python)

Code before:
        The color of the selected button.
    labels : list of `.Text`
        The button labels.
    value_selected : str
        The label text of the currently selected button.
    index_selected : int
        The index of the selected button.
    """

    def __init__(self, ax, labels, active=0, activecolor=None, *,
                 layout=None, useblit=True, label_props=None, radio_props=None):
        """
        Add radio buttons to an `~.axes.Axes`.

        Parameters
        ----------
        ax : `~matplotlib.axes.Axes`
            The Axes to add the buttons to.
        labels : list of str
            The button labels.
        active : int
            The index of the initially selected button.
        activecolor : :mpltype:`color`
            The color of the selected button. The default is ``'blue'`` if not
            specified here or in *radio_props*.
        layout : None, {"vertical", "horizontal"} or (int, int), default: None
            The layout of the radio buttons. Options are:

            - ``None``: Use legacy vertical layout (default, keeps backward
              compatibility with fixed button and label positions).
            - ``"vertical"``: Arrange buttons in a single column with
              dynamic positioning based on text widths.
            - ``"horizontal"``: Arrange buttons in a single row with
              dynamic positioning based on text widths.
            - ``(rows, cols)`` tuple: Arrange buttons in a grid with the
              specified number of rows and columns. Buttons are placed
              left-to-right, top-to-bottom with dynamic positioning.

            .. versionadded:: 3.11
        useblit : bool, default: True
            Use blitting for faster drawing if supported by the backend.
            See the tutorial :ref:`blitting` for details.

            .. versionadded:: 3.7

        label_props : dict of lists, optional
            Dictionary of `.Text` properties to be used for the labels. Each
            dictionary value should be a list of at least a single element. If
            the list is of length M, its values are cycled such that the Nth
            label gets the (N mod M) property.


Review comment (suggestion):
```suggestion
        layout : None or {"vertical", "horizontal"} or (int, int), default: None
```
numpydoc convention is to separate all types by "or"

Code after:
        self._rendercursor()

    @_call_with_reparented_event
    def _resize(self, event):
        self.stop_typing()

    @_call_with_reparented_event
    def _motion(self, event):
        if self.ignore(event):
            return
        c = self.hovercolor if self.ax.contains(event)[0] else self.color
        if not colors.same_color(c, self.ax.get_facecolor()):
            self.ax.set_facecolor(c)
            if self.drawon:
                self.ax.get_figure(root=True).canvas.draw()

    def on_text_change(self, func):
        """
        When the text changes, call this *func* with event.

        A connection id is returned which can be used to disconnect.
        """
        return self._observers.connect('change', lambda text: func(text))

    def on_submit(self, func):
        """
        When the user hits enter or leaves the submission box, call this
        *func* with event.

        A connection id is returned which can be used to disconnect.
        """
        return self._observers.connect('submit', lambda text: func(text))

    def disconnect(self, cid):
        """Remove the observer with connection id *cid*."""
        self._observers.disconnect(cid)


class RadioButtons(_Buttons):
    """
    A GUI neutral radio button.

    For the buttons to remain responsive you must keep a reference to this
    object.

    Connect to the RadioButtons with the `~._Buttons.on_clicked` method.

    Attributes
    ----------
    ax : `~matplotlib.axes.Axes`
        The parent Axes for the widget.