Displaying Radio buttons horizontally in matplotlib

。_饼干妹妹 提交于 2019-12-24 01:14:58

问题


I am using the matplotlib.widgets to create radio buttons in my widgets, the buttons coming are stacked vertically, I would like them to be stacked horizontally.

MVCE:

import matplotlib.pyplot as plt
from matplotlib.widgets import RadioButtons
plt.subplots_adjust(left=0.2)
rax = plt.axes([0.5,0.05,0.1,0.1])
radio =  RadioButtons(rax ,['1','2','3'], active=0, activecolor='blue' )
plt.show()

As you can see with this example you can get the radio buttons like this ,

I am wondering is there a way to stack these radio buttons horizontally.


回答1:


There is currently an attempt to introduce an orientation argument to RadioButtons in PR #13374; this has not yet been finalized.

As I had commented in this PR, an alternative option would be to use a scatter plot for the buttons. The following shows how I would imagine this implementation. There are two main enhancements compared to the usual buttons:

  • Radio buttons are always round independent of the size of the axes.
  • They can be aligned arbitrarily, in particular horizontally.

This is achieved by creating a legend internally, which has all the required options readily available. Any valid arguments to Legend can be used for the Buttons as well.

import matplotlib.pyplot as plt
from matplotlib.widgets import AxesWidget, RadioButtons

class MyRadioButtons(RadioButtons):

    def __init__(self, ax, labels, active=0, activecolor='blue', size=49,
                 orientation="vertical", **kwargs):
        """
        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 : color
            The color of the selected button.
        size : float
            Size of the radio buttons
        orientation : str
            The orientation of the buttons: 'vertical' (default), or 'horizontal'.
        Further parameters are passed on to `Legend`.
        """
        AxesWidget.__init__(self, ax)
        self.activecolor = activecolor
        axcolor = ax.get_facecolor()
        self.value_selected = None

        ax.set_xticks([])
        ax.set_yticks([])
        ax.set_navigate(False)

        circles = []
        for i, label in enumerate(labels):
            if i == active:
                self.value_selected = label
                facecolor = activecolor
            else:
                facecolor = axcolor
            p = ax.scatter([],[], s=size, marker="o", edgecolor='black',
                           facecolor=facecolor)
            circles.append(p)
        if orientation == "horizontal":
            kwargs.update(ncol=len(labels), mode="expand")
        kwargs.setdefault("frameon", False)    
        self.box = ax.legend(circles, labels, loc="center", **kwargs)
        self.labels = self.box.texts
        self.circles = self.box.legendHandles
        for c in self.circles:
            c.set_picker(5)
        self.cnt = 0
        self.observers = {}

        self.connect_event('pick_event', self._clicked)


    def _clicked(self, event):
        if (self.ignore(event) or event.mouseevent.button != 1 or
            event.mouseevent.inaxes != self.ax):
            return
        if event.artist in self.circles:
            self.set_active(self.circles.index(event.artist))

Use it as

plt.subplots_adjust(left=0.2)
rax = plt.axes([0.5,0.05,0.4,0.07])
radio =  MyRadioButtons(rax ,['1','2','3'], active=0, activecolor='crimson',
                        orientation="horizontal")

plt.show()

Or

rax = plt.axes([0.2,0.5,0.25,0.1])
radio =  MyRadioButtons(rax ,["AA", "BB", "CC", "DD"], ncol=2)



来源:https://stackoverflow.com/questions/55095111/displaying-radio-buttons-horizontally-in-matplotlib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!