Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcd8420a

Browse files
authored
Merge pull request#24474 from chahak13/make_checkbox_square_again
Use scatter for check boxes and set facecolors correctly in check boxes and radio buttons
2 parents9f3c6f4 +788a0d1 commitcd8420a

File tree

4 files changed

+180
-50
lines changed

4 files changed

+180
-50
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
``CheckButtons.rectangles`` and ``CheckButtons.lines``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
``CheckButtons.rectangles`` and ``CheckButtons.lines`` are deprecated.
4+
(``CheckButtons`` now draws itself using `~.Axes.scatter`.)

‎doc/api/prev_api_changes/api_changes_2.1.0.rst‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,8 @@ The ``shading`` kwarg to `~matplotlib.axes.Axes.pcolor` has been
422422
removed. Set ``edgecolors`` appropriately instead.
423423

424424

425-
Functions removed from the `.lines` module
426-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
425+
Functions removed from the ``lines`` module
426+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
427427

428428
The:mod:`matplotlib.lines` module no longer imports the
429429
``pts_to_prestep``, ``pts_to_midstep`` and ``pts_to_poststep``

‎lib/matplotlib/tests/test_widgets.py‎

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
importmatplotlib.colorsasmcolors
88
importmatplotlib.widgetsaswidgets
99
importmatplotlib.pyplotasplt
10+
frommatplotlib.patchesimportRectangle
11+
frommatplotlib.linesimportLine2D
1012
frommatplotlib.testing.decoratorsimportcheck_figures_equal,image_comparison
1113
frommatplotlib.testing.widgetsimport (click_and_drag,do_event,get_ax,
1214
mock_event,noop)
@@ -1006,8 +1008,10 @@ def test_check_radio_buttons_image():
10061008
rb=widgets.RadioButtons(rax1, ('Radio 1','Radio 2','Radio 3'))
10071009
withpytest.warns(DeprecationWarning):
10081010
rb.circles# Trigger the old-style elliptic radiobuttons.
1009-
widgets.CheckButtons(rax2, ('Check 1','Check 2','Check 3'),
1010-
(False,True,True))
1011+
cb=widgets.CheckButtons(rax2, ('Check 1','Check 2','Check 3'),
1012+
(False,True,True))
1013+
withpytest.warns(DeprecationWarning):
1014+
cb.rectangles# Trigger old-style Rectangle check boxes
10111015

10121016

10131017
@check_figures_equal(extensions=["png"])
@@ -1020,6 +1024,67 @@ def test_radio_buttons(fig_test, fig_ref):
10201024
ax.text(.25,1/3,"coffee",transform=ax.transAxes,va="center")
10211025

10221026

1027+
@check_figures_equal(extensions=["png"])
1028+
deftest_check_buttons(fig_test,fig_ref):
1029+
widgets.CheckButtons(fig_test.subplots(), ["tea","coffee"], [True,True])
1030+
ax=fig_ref.add_subplot(xticks=[],yticks=[])
1031+
ax.scatter([.15,.15], [2/3,1/3],marker='s',transform=ax.transAxes,
1032+
s=(plt.rcParams["font.size"]/2)**2,c=["none","none"])
1033+
ax.scatter([.15,.15], [2/3,1/3],marker='x',transform=ax.transAxes,
1034+
s=(plt.rcParams["font.size"]/2)**2,c=["k","k"])
1035+
ax.text(.25,2/3,"tea",transform=ax.transAxes,va="center")
1036+
ax.text(.25,1/3,"coffee",transform=ax.transAxes,va="center")
1037+
1038+
1039+
@check_figures_equal(extensions=["png"])
1040+
deftest_check_buttons_rectangles(fig_test,fig_ref):
1041+
# Test should be removed once .rectangles is removed
1042+
cb=widgets.CheckButtons(fig_test.subplots(), ["",""],
1043+
[False,False])
1044+
withpytest.warns(DeprecationWarning):
1045+
cb.rectangles
1046+
ax=fig_ref.add_subplot(xticks=[],yticks=[])
1047+
ys= [2/3,1/3]
1048+
dy=1/3
1049+
w,h=dy/2,dy/2
1050+
rectangles= [
1051+
Rectangle(xy=(0.05,ys[i]-h/2),width=w,height=h,
1052+
edgecolor="black",
1053+
facecolor="none",
1054+
transform=ax.transAxes
1055+
)
1056+
fori,yinenumerate(ys)
1057+
]
1058+
forrectangleinrectangles:
1059+
ax.add_patch(rectangle)
1060+
1061+
1062+
@check_figures_equal(extensions=["png"])
1063+
deftest_check_buttons_lines(fig_test,fig_ref):
1064+
# Test should be removed once .lines is removed
1065+
cb=widgets.CheckButtons(fig_test.subplots(), ["",""], [True,True])
1066+
withpytest.warns(DeprecationWarning):
1067+
cb.lines
1068+
forrectangleincb._rectangles:
1069+
rectangle.set_visible(False)
1070+
ax=fig_ref.add_subplot(xticks=[],yticks=[])
1071+
ys= [2/3,1/3]
1072+
dy=1/3
1073+
w,h=dy/2,dy/2
1074+
lineparams= {'color':'k','linewidth':1.25,
1075+
'transform':ax.transAxes,
1076+
'solid_capstyle':'butt'}
1077+
fori,yinenumerate(ys):
1078+
x,y=0.05,y-h/2
1079+
l1=Line2D([x,x+w], [y+h,y],**lineparams)
1080+
l2=Line2D([x,x+w], [y,y+h],**lineparams)
1081+
1082+
l1.set_visible(True)
1083+
l2.set_visible(True)
1084+
ax.add_line(l1)
1085+
ax.add_line(l2)
1086+
1087+
10231088
deftest_slider_slidermin_slidermax_invalid():
10241089
fig,ax=plt.subplots()
10251090
# test min/max with floats

‎lib/matplotlib/widgets.py‎

Lines changed: 107 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,43 +1002,23 @@ def __init__(self, ax, labels, actives=None):
10021002
ifactivesisNone:
10031003
actives= [False]*len(labels)
10041004

1005-
iflen(labels)>1:
1006-
dy=1./ (len(labels)+1)
1007-
ys=np.linspace(1-dy,dy,len(labels))
1008-
else:
1009-
dy=0.25
1010-
ys= [0.5]
1011-
1012-
axcolor=ax.get_facecolor()
1013-
1014-
self.labels= []
1015-
self.lines= []
1016-
self.rectangles= []
1017-
1018-
lineparams= {'color':'k','linewidth':1.25,
1019-
'transform':ax.transAxes,'solid_capstyle':'butt'}
1020-
fory,label,activeinzip(ys,labels,actives):
1021-
t=ax.text(0.25,y,label,transform=ax.transAxes,
1022-
horizontalalignment='left',
1023-
verticalalignment='center')
1024-
1025-
w,h=dy/2,dy/2
1026-
x,y=0.05,y-h/2
1027-
1028-
p=Rectangle(xy=(x,y),width=w,height=h,edgecolor='black',
1029-
facecolor=axcolor,transform=ax.transAxes)
1005+
ys=np.linspace(1,0,len(labels)+2)[1:-1]
1006+
text_size=mpl.rcParams["font.size"]/2
10301007

1031-
l1=Line2D([x,x+w], [y+h,y],**lineparams)
1032-
l2=Line2D([x,x+w], [y,y+h],**lineparams)
1008+
self.labels= [
1009+
ax.text(0.25,y,label,transform=ax.transAxes,
1010+
horizontalalignment="left",verticalalignment="center")
1011+
fory,labelinzip(ys,labels)]
10331012

1034-
l1.set_visible(active)
1035-
l2.set_visible(active)
1036-
self.labels.append(t)
1037-
self.rectangles.append(p)
1038-
self.lines.append((l1,l2))
1039-
ax.add_patch(p)
1040-
ax.add_line(l1)
1041-
ax.add_line(l2)
1013+
self._squares=ax.scatter(
1014+
[0.15]*len(ys),ys,marker='s',s=text_size**2,
1015+
c="none",linewidth=1,transform=ax.transAxes,edgecolor="k"
1016+
)
1017+
self._crosses=ax.scatter(
1018+
[0.15]*len(ys),ys,marker='x',linewidth=1,s=text_size**2,
1019+
c=["k"ifactiveelse"none"foractiveinactives],
1020+
transform=ax.transAxes
1021+
)
10421022

10431023
self.connect_event('button_press_event',self._clicked)
10441024

@@ -1047,11 +1027,27 @@ def __init__(self, ax, labels, actives=None):
10471027
def_clicked(self,event):
10481028
ifself.ignore(event)orevent.button!=1orevent.inaxes!=self.ax:
10491029
return
1050-
fori, (p,t)inenumerate(zip(self.rectangles,self.labels)):
1051-
if (t.get_window_extent().contains(event.x,event.y)or
1052-
p.get_window_extent().contains(event.x,event.y)):
1053-
self.set_active(i)
1054-
break
1030+
pclicked=self.ax.transAxes.inverted().transform((event.x,event.y))
1031+
distances= {}
1032+
ifhasattr(self,"_rectangles"):
1033+
fori, (p,t)inenumerate(zip(self._rectangles,self.labels)):
1034+
x0,y0=p.get_xy()
1035+
if (t.get_window_extent().contains(event.x,event.y)
1036+
or (x0<=pclicked[0]<=x0+p.get_width()
1037+
andy0<=pclicked[1]<=y0+p.get_height())):
1038+
distances[i]=np.linalg.norm(pclicked-p.get_center())
1039+
else:
1040+
_,square_inds=self._squares.contains(event)
1041+
coords=self._squares.get_offset_transform().transform(
1042+
self._squares.get_offsets()
1043+
)
1044+
fori,tinenumerate(self.labels):
1045+
if (iinsquare_inds["ind"]
1046+
ort.get_window_extent().contains(event.x,event.y)):
1047+
distances[i]=np.linalg.norm(pclicked-coords[i])
1048+
iflen(distances)>0:
1049+
closest=min(distances,key=distances.get)
1050+
self.set_active(closest)
10551051

10561052
defset_active(self,index):
10571053
"""
@@ -1072,9 +1068,20 @@ def set_active(self, index):
10721068
ifindexnotinrange(len(self.labels)):
10731069
raiseValueError(f'Invalid CheckButton index:{index}')
10741070

1075-
l1,l2=self.lines[index]
1076-
l1.set_visible(notl1.get_visible())
1077-
l2.set_visible(notl2.get_visible())
1071+
cross_facecolors=self._crosses.get_facecolor()
1072+
cross_facecolors[index]=colors.to_rgba(
1073+
"black"
1074+
ifcolors.same_color(
1075+
cross_facecolors[index],colors.to_rgba("none")
1076+
)
1077+
else"none"
1078+
)
1079+
self._crosses.set_facecolor(cross_facecolors)
1080+
1081+
ifhasattr(self,"_lines"):
1082+
l1,l2=self._lines[index]
1083+
l1.set_visible(notl1.get_visible())
1084+
l2.set_visible(notl2.get_visible())
10781085

10791086
ifself.drawon:
10801087
self.ax.figure.canvas.draw()
@@ -1086,7 +1093,8 @@ def get_status(self):
10861093
"""
10871094
Return a list of the status (True/False) of all of the check buttons.
10881095
"""
1089-
return [l1.get_visible()for (l1,l2)inself.lines]
1096+
return [notcolors.same_color(color,colors.to_rgba("none"))
1097+
forcolorinself._crosses.get_facecolors()]
10901098

10911099
defon_clicked(self,func):
10921100
"""
@@ -1100,6 +1108,57 @@ def disconnect(self, cid):
11001108
"""Remove the observer with connection id *cid*."""
11011109
self._observers.disconnect(cid)
11021110

1111+
@_api.deprecated("3.7")
1112+
@property
1113+
defrectangles(self):
1114+
ifnothasattr(self,"_rectangles"):
1115+
ys=np.linspace(1,0,len(self.labels)+2)[1:-1]
1116+
dy=1./ (len(self.labels)+1)
1117+
w,h=dy/2,dy/2
1118+
rectangles=self._rectangles= [
1119+
Rectangle(xy=(0.05,ys[i]-h/2),width=w,height=h,
1120+
edgecolor="black",
1121+
facecolor="none",
1122+
transform=self.ax.transAxes
1123+
)
1124+
fori,yinenumerate(ys)
1125+
]
1126+
self._squares.set_visible(False)
1127+
forrectangleinrectangles:
1128+
self.ax.add_patch(rectangle)
1129+
ifnothasattr(self,"_lines"):
1130+
with_api.suppress_matplotlib_deprecation_warning():
1131+
_=self.lines
1132+
returnself._rectangles
1133+
1134+
@_api.deprecated("3.7")
1135+
@property
1136+
deflines(self):
1137+
ifnothasattr(self,"_lines"):
1138+
ys=np.linspace(1,0,len(self.labels)+2)[1:-1]
1139+
self._crosses.set_visible(False)
1140+
dy=1./ (len(self.labels)+1)
1141+
w,h=dy/2,dy/2
1142+
self._lines= []
1143+
current_status=self.get_status()
1144+
lineparams= {'color':'k','linewidth':1.25,
1145+
'transform':self.ax.transAxes,
1146+
'solid_capstyle':'butt'}
1147+
fori,yinenumerate(ys):
1148+
x,y=0.05,y-h/2
1149+
l1=Line2D([x,x+w], [y+h,y],**lineparams)
1150+
l2=Line2D([x,x+w], [y,y+h],**lineparams)
1151+
1152+
l1.set_visible(current_status[i])
1153+
l2.set_visible(current_status[i])
1154+
self._lines.append((l1,l2))
1155+
self.ax.add_patch(l1)
1156+
self.ax.add_patch(l2)
1157+
ifnothasattr(self,"_rectangles"):
1158+
with_api.suppress_matplotlib_deprecation_warning():
1159+
_=self.rectangles
1160+
returnself._lines
1161+
11031162

11041163
classTextBox(AxesWidget):
11051164
"""
@@ -1457,8 +1516,10 @@ def set_active(self, index):
14571516
ifindexnotinrange(len(self.labels)):
14581517
raiseValueError(f'Invalid RadioButton index:{index}')
14591518
self.value_selected=self.labels[index].get_text()
1460-
self._buttons.get_facecolor()[:]=colors.to_rgba("none")
1461-
self._buttons.get_facecolor()[index]=colors.to_rgba(self.activecolor)
1519+
button_facecolors=self._buttons.get_facecolor()
1520+
button_facecolors[:]=colors.to_rgba("none")
1521+
button_facecolors[index]=colors.to_rgba(self.activecolor)
1522+
self._buttons.set_facecolor(button_facecolors)
14621523
ifhasattr(self,"_circles"):# Remove once circles is removed.
14631524
fori,pinenumerate(self._circles):
14641525
p.set_facecolor(self.activecolorifi==indexelse"none")

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp