Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9b13608

Browse files
authored
Merge pull request #30803 from doronbehar/RadioButtonsGrid
{Radio,Check}Buttons: Add 2D grid labels layout support
2 parents 08fe8bc + 0cc8ba5 commit 9b13608

6 files changed

Lines changed: 306 additions & 21 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
RadioButtons and CheckButtons widgets support flexible layouts
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The `.widgets.RadioButtons` and `.widgets.CheckButtons` widgets now support
5+
arranging buttons in different layouts via the new *layout* parameter. You can
6+
arrange buttons vertically (default), horizontally, or in a 2D grid by passing
7+
a ``(rows, cols)`` tuple.
8+
9+
See :doc:`/gallery/widgets/radio_buttons_grid` for a ``(rows, cols)`` example.
10+
11+
.. plot::
12+
:include-source: true
13+
:alt: Multiple sine waves with checkboxes to toggle their visibility.
14+
15+
import matplotlib.pyplot as plt
16+
import numpy as np
17+
from matplotlib.widgets import CheckButtons
18+
19+
t = np.arange(0.0, 2.0, 0.01)
20+
s0 = np.sin(2*np.pi*t)
21+
s1 = np.sin(4*np.pi*t)
22+
s2 = np.sin(6*np.pi*t)
23+
s3 = np.sin(8*np.pi*t)
24+
25+
fig, axes = plt.subplot_mosaic(
26+
[['main'], ['buttons']],
27+
height_ratios=[8, 1],
28+
layout="constrained",
29+
)
30+
31+
l0, = axes['main'].plot(t, s0, lw=2, color='red', label='2 Hz')
32+
l1, = axes['main'].plot(t, s1, lw=2, color='green', label='4 Hz')
33+
l2, = axes['main'].plot(t, s2, lw=2, color='blue', label='6 Hz')
34+
l3, = axes['main'].plot(t, s3, lw=2, color='purple', label='8 Hz')
35+
axes['main'].set_xlabel('Time (s)')
36+
axes['main'].set_ylabel('Amplitude')
37+
38+
lines_by_label = {l.get_label(): l for l in [l0, l1, l2, l3]}
39+
40+
axes['buttons'].set_facecolor('0.9')
41+
check = CheckButtons(
42+
axes['buttons'],
43+
labels=lines_by_label.keys(),
44+
actives=[l.get_visible() for l in lines_by_label.values()],
45+
layout='horizontal'
46+
)
47+
48+
def callback(label):
49+
ln = lines_by_label[label]
50+
ln.set_visible(not ln.get_visible())
51+
fig.canvas.draw_idle()
52+
53+
check.on_clicked(callback)
54+
plt.show()
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""
2+
==================
3+
Radio Buttons Grid
4+
==================
5+
6+
Using radio buttons in a 2D grid layout.
7+
8+
Radio buttons can be arranged in a 2D grid by passing a ``(rows, cols)``
9+
tuple to the *layout* parameter. This is useful when you have multiple
10+
related options that are best displayed in a grid format rather than a
11+
vertical list.
12+
13+
In this example, we create a color picker using a 2D grid of radio buttons
14+
to select the line color of a plot.
15+
"""
16+
17+
import matplotlib.pyplot as plt
18+
import numpy as np
19+
20+
from matplotlib.widgets import RadioButtons
21+
22+
# Generate sample data
23+
t = np.arange(0.0, 2.0, 0.01)
24+
s = np.sin(2 * np.pi * t)
25+
26+
fig, (ax_plot, ax_buttons) = plt.subplots(
27+
1,
28+
2,
29+
figsize=(8, 4),
30+
width_ratios=[4, 1.4],
31+
)
32+
33+
# Create initial plot
34+
(line,) = ax_plot.plot(t, s, lw=2, color="red")
35+
ax_plot.set_xlabel("Time (s)")
36+
ax_plot.set_ylabel("Amplitude")
37+
ax_plot.set_title("Sine Wave - Click a color!")
38+
ax_plot.grid(True, alpha=0.3)
39+
40+
# Configure the radio buttons axes
41+
ax_buttons.set_facecolor("0.9")
42+
ax_buttons.set_title("Line Color", fontsize=12, pad=10)
43+
# Create a 2D grid of color options (3 rows x 2 columns)
44+
colors = ["red", "yellow", "green", "purple", "brown", "gray"]
45+
radio = RadioButtons(ax_buttons, colors, layout=(3, 2))
46+
47+
48+
def color_func(label):
49+
"""Update the line color based on selected button."""
50+
line.set_color(label)
51+
fig.canvas.draw()
52+
53+
54+
radio.on_clicked(color_func)
55+
56+
plt.show()
57+
58+
# %%
59+
#
60+
# .. admonition:: References
61+
#
62+
# The use of the following functions, methods, classes and modules is shown
63+
# in this example:
64+
#
65+
# - `matplotlib.widgets.RadioButtons`
66+
#
67+
# .. tags::
68+
#
69+
# styling: color
70+
# styling: conditional
71+
# plot-type: line
72+
# level: intermediate
73+
# purpose: showcase
21.5 KB
Loading

lib/matplotlib/tests/test_widgets.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,29 @@ def test_radio_buttons_props(fig_test, fig_ref):
11641164
cb.set_radio_props({**radio_props, 's': (24 / 2)**2})
11651165

11661166

1167+
@image_comparison(['check_radio_grid_buttons.png'], style='mpl20', remove_text=True)
1168+
def test_radio_grid_buttons():
1169+
fig = plt.figure()
1170+
rb_horizontal = widgets.RadioButtons(
1171+
fig.add_axes((0.1, 0.05, 0.65, 0.05)),
1172+
["tea", "coffee", "chocolate milk", "water", "soda", "coke"],
1173+
layout='horizontal',
1174+
active=4,
1175+
)
1176+
cb_grid = widgets.CheckButtons(
1177+
fig.add_axes((0.1, 0.15, 0.25, 0.05*3)),
1178+
["Chicken", "Salad", "Rice", "Sushi", "Pizza", "Fries"],
1179+
layout=(3, 2),
1180+
actives=[True, True, False, False, False, True],
1181+
)
1182+
rb_vertical = widgets.RadioButtons(
1183+
fig.add_axes((0.1, 0.35, 0.2, 0.05*4)),
1184+
["Trinity Cream", "Cake", "Ice Cream", "Muhallebi"],
1185+
layout='vertical',
1186+
active=3,
1187+
)
1188+
1189+
11671190
def test_radio_button_active_conflict(ax):
11681191
with pytest.warns(UserWarning,
11691192
match=r'Both the \*activecolor\* parameter'):
@@ -1229,8 +1252,7 @@ def test__buttons_callbacks(ax, widget):
12291252
"button_press_event",
12301253
ax,
12311254
ax.transData.inverted().transform(ax.transAxes.transform(
1232-
# (x, y) of the 0th button defined at
1233-
# `{Check,Radio}Buttons._init_props`
1255+
# (x, y) of the 0th button defined at `_Buttons._init_layout`
12341256
(0.15, 0.5),
12351257
)),
12361258
1,

0 commit comments

Comments
 (0)