Skip to content

Commit 7ea2b58

Browse files
committed
ENH: Add a LockableBbox type.
This encapsulates another Bbox and locks one or more ends so that they cannot be changed even if the corresponding element in the underlying Bbox does.
1 parent c38205a commit 7ea2b58

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

lib/matplotlib/transforms.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,155 @@ def get_points(self):
10951095
return points
10961096

10971097

1098+
class LockableBbox(BboxBase):
1099+
"""
1100+
A :class:`Bbox` where some elements may be locked at certain values.
1101+
1102+
When the child bounding box changes, the bounds of this bbox will update
1103+
accordingly with the exception of the locked elements.
1104+
"""
1105+
def __init__(self, bbox, x0=None, y0=None, x1=None, y1=None, **kwargs):
1106+
"""
1107+
Parameters
1108+
----------
1109+
bbox : Bbox
1110+
The child bounding box to wrap.
1111+
1112+
x0 : float or None
1113+
The locked value for x0, or None to leave unlocked.
1114+
1115+
y0 : float or None
1116+
The locked value for y0, or None to leave unlocked.
1117+
1118+
x1 : float or None
1119+
The locked value for x1, or None to leave unlocked.
1120+
1121+
y1 : float or None
1122+
The locked value for y1, or None to leave unlocked.
1123+
1124+
"""
1125+
if not bbox.is_bbox:
1126+
raise ValueError("'bbox' is not a bbox")
1127+
1128+
BboxBase.__init__(self, **kwargs)
1129+
self._bbox = bbox
1130+
self.set_children(bbox)
1131+
self._points = None
1132+
fp = [x0, y0, x1, y1]
1133+
mask = [val is None for val in fp]
1134+
self._locked_points = np.ma.array(fp, np.float_,
1135+
mask=mask).reshape((2, 2))
1136+
1137+
def __repr__(self):
1138+
return "LockableBbox(%r, %r)" % (self._bbox, self._locked_points)
1139+
1140+
def get_points(self):
1141+
if self._invalid:
1142+
points = self._bbox.get_points()
1143+
self._points = np.where(self._locked_points.mask,
1144+
points,
1145+
self._locked_points)
1146+
self._invalid = 0
1147+
return self._points
1148+
get_points.__doc__ = Bbox.get_points.__doc__
1149+
1150+
if DEBUG:
1151+
_get_points = get_points
1152+
1153+
def get_points(self):
1154+
points = self._get_points()
1155+
self._check(points)
1156+
return points
1157+
1158+
def set_locked_x0(self, x0):
1159+
"""
1160+
Set the value to be used for the locked x0.
1161+
1162+
Parameters
1163+
----------
1164+
x0 : float or None
1165+
The locked value for x0, or None to unlock.
1166+
"""
1167+
self._locked_points.mask[0, 0] = x0 is None
1168+
self._locked_points.data[0, 0] = x0
1169+
self.invalidate()
1170+
1171+
def get_locked_x0(self):
1172+
"""
1173+
Get the value used for the locked x0.
1174+
"""
1175+
if self._locked_points.mask[0, 0]:
1176+
return None
1177+
else:
1178+
return self._locked_points[0, 0]
1179+
1180+
def set_locked_y0(self, y0):
1181+
"""
1182+
Set the value to be used for the locked y0.
1183+
1184+
Parameters
1185+
----------
1186+
y0 : float or None
1187+
The locked value for y0, or None to unlock.
1188+
"""
1189+
self._locked_points.mask[0, 1] = y0 is None
1190+
self._locked_points.data[0, 1] = y0
1191+
self.invalidate()
1192+
1193+
def get_locked_y0(self):
1194+
"""
1195+
Get the value used for the locked y0.
1196+
"""
1197+
if self._locked_points.mask[0, 1]:
1198+
return None
1199+
else:
1200+
return self._locked_points[0, 1]
1201+
1202+
def set_locked_x1(self, x1):
1203+
"""
1204+
Set the value to be used for the locked x1.
1205+
1206+
Parameters
1207+
----------
1208+
x1 : float or None
1209+
The locked value for x1, or None to unlock.
1210+
"""
1211+
self._locked_points.mask[1, 0] = x1 is None
1212+
self._locked_points.data[1, 0] = x1
1213+
self.invalidate()
1214+
1215+
def get_locked_x1(self):
1216+
"""
1217+
Get the value used for the locked x1.
1218+
"""
1219+
if self._locked_points.mask[1, 0]:
1220+
return None
1221+
else:
1222+
return self._locked_points[1, 0]
1223+
1224+
def set_locked_y1(self, y1):
1225+
"""
1226+
Set the value to be used for the locked y1.
1227+
1228+
Parameters
1229+
----------
1230+
y1 : float or None
1231+
The locked value for y1, or None to unlock.
1232+
"""
1233+
self._locked_points.mask[1, 1] = y1 is None
1234+
self._locked_points.data[1, 1] = y1
1235+
self.invalidate()
1236+
1237+
def get_locked_y1(self):
1238+
"""
1239+
Get the value used for the locked y1.
1240+
"""
1241+
if self._locked_points.mask[1, 1]:
1242+
return None
1243+
else:
1244+
return self._locked_points[1, 1]
1245+
1246+
10981247
class Transform(TransformNode):
10991248
"""
11001249
The base class of all :class:`TransformNode` instances that

0 commit comments

Comments
 (0)