8000 Add blitting support to the RadioButtons widget · matplotlib/matplotlib@f6e123b · GitHub
[go: up one dir, main page]

Skip to content

Commit f6e123b

Browse files
committed
Add blitting support to the RadioButtons widget
1 parent 33669e9 commit f6e123b

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

lib/matplotlib/widgets.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,8 @@ class RadioButtons(AxesWidget):
14561456
The label text of the currently selected button.
14571457
"""
14581458

1459-
def __init__(self, ax, labels, active=0, activecolor='blue'):
1459+
def __init__(self, ax, labels, active=0, activecolor='blue', *,
1460+
useblit=True):
14601461
"""
14611462
Add radio buttons to an `~.axes.Axes`.
14621463
@@ -1470,6 +1471,9 @@ def __init__(self, ax, labels, active=0, activecolor='blue'):
14701471
The index of the initially selected button.
14711472
activecolor : color
14721473
The color of the selected button.
1474+
useblit : bool, default: True
1475+
Use blitting for faster drawing if supported by the backend.
1476+
See the tutorial :doc:`/tutorials/advanced/blitting` for details.
14731477
"""
14741478
super().__init__(ax)
14751479
self.activecolor = activecolor
@@ -1482,19 +1486,34 @@ def __init__(self, ax, labels, active=0, activecolor='blue'):
14821486
ys = np.linspace(1, 0, len(labels) + 2)[1:-1]
14831487
text_size = mpl.rcParams["font.size"] / 2
14841488

1489+
self._useblit = useblit and self.canvas.supports_blit
1490+
self._background = None
1491+
14851492
self.labels = [
14861493
ax.text(0.25, y, label, transform=ax.transAxes,
14871494
horizontalalignment="left", verticalalignment="center")
14881495
for y, label in zip(ys, labels)]
14891496
self._buttons = ax.scatter(
14901497
[.15] * len(ys), ys, transform=ax.transAxes, s=text_size**2,
14911498
c=[activecolor if i == active else "none" for i in range(len(ys))],
1492-
edgecolor="black")
1499+
edgecolor="black", animated=self._useblit)
14931500

14941501
self.connect_event('button_press_event', self._clicked)
1502+
if self._useblit:
1503+
self.connect_event('draw_event', self._clear)
14951504

14961505
self._observers = cbook.CallbackRegistry(signals=["clicked"])
14971506

1507+
def _clear(self, event):
1508+
"""Internal event handler to clear the buttons."""
1509+
if self.ignore(event):
1510+
return
1511+
self._background = self.canvas.copy_from_bbox(self.ax.bbox)
1512+
self.ax.draw_artist(self._buttons)
1513+
if hasattr(self, "_circles"):
1514+
for circle in self._circles:
1515+
self.ax.draw_artist(circle)
1516+
14981517
def _clicked(self, event):
14991518
if self.ignore(event) or event.button != 1 or event.inaxes != self.ax:
15001519
return
@@ -1533,8 +1552,20 @@ def set_active(self, index):
15331552
if hasattr(self, "_circles"): # Remove once circles is removed.
15341553
for i, p in enumerate(self._circles):
15351554
p.set_facecolor(self.activecolor if i == index else "none")
1555+
if self.drawon and self._useblit:
1556+
self.ax.draw_artist(p)
15361557
if self.drawon:
1537-
self.ax.figure.canvas.draw()
1558+
if self._useblit:
1559+
if self._background is not None:
1560+
self.canvas.restore_region(self._background)
1561+
self.ax.draw_artist(self._buttons)
1562+
if hasattr(self, "_circles"):
1563+
for p in self._circles:
1564+
self.ax.draw_artist(p)
1565+
self.canvas.blit(self.ax.bbox)
1566+
else:
1567+
self.canvas.draw()
1568+
15381569
if self.eventson:
15391570
self._observers.process('clicked', self.labels[index].get_text())
15401571

@@ -1558,7 +1589,8 @@ def circles(self):
15581589
circles = self._circles = [
15591590
Circle(xy=self._buttons.get_offsets()[i], edgecolor="black",
15601591
facecolor=self._buttons.get_facecolor()[i],
1561-
radius=radius, transform=self.ax.transAxes)
1592+
radius=radius, transform=self.ax.transAxes,
1593+
animated=self._useblit)
15621594
for i in range(len(self.labels))]
15631595
self._buttons.set_visible(False)
15641596
for circle in circles:

0 commit comments

Comments
 (0)
0