8000 add EventCollection class to collections · matplotlib/matplotlib@9e908d9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e908d9

Browse files
committed
add EventCollection class to collections
1 parent ac957b2 commit 9e908d9

File tree

1 file changed

+252
-0
lines changed

1 file changed

+252
-0
lines changed

lib/matplotlib/collections.py

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,258 @@ def get_color(self):
10681068
get_colors = get_color # for compatibility with old versions
10691069

10701070

1071+
class EventCollection(LineCollection):
1072+
'''
1073+
A collection of discrete events.
1074+
1075+
An event is a 1-dimensional value, usually the position of something along
1076+
an axis, such as time or length. Events do not have an amplitude. They
1077+
are displayed as v
1078+
'''
1079+
1080+
def __init__(self,
1081+
positions, # Can be None.
1082+
orientation=None,
1083+
lineoffset=0,
1084+
linelength=1,
1085+
linewidth=None,
1086+
color=None,
1087+
linestyle='solid',
1088+
antialiased=None,
1089+
**kwargs
1090+
):
1091+
"""
1092+
*positions*
1093+
a sequence of numerical values or a 1D numpy array. Can be None
1094+
1095+
*orientation* [ 'horizontal' | 'vertical' | None ]
1096+
defaults to 'horizontal' if not specified or None
1097+
1098+
*lineoffset*
1099+
a single numerical value, corresponding to the offset of the center
1100+
of the markers from the origin
1101+
1102+
*linelength*
1103+
a single numerical value, corresponding to the total height of the
1104+
marker (i.e. the marker stretches from lineoffset+linelength/2 to
1105+
lineoffset-linelength/2). Defaults to 1
1106+
1107+
*linewidth*
1108+
a single numerical value
1109+
1110+
*color*
1111+
must be a sequence of RGBA tuples (eg arbitrary color
1112+
strings, etc, not allowed).
1113+
1114+
*linestyle* [ 'solid' | 'dashed' | 'dashdot' | 'dotted' ]
1115+
1116+
*antialiased*
1117+
1 or 2
1118+
1119+
If *linewidth*, *color*, or *antialiased* is None, they
1120+
default to their rcParams setting, in sequence form.
1121+
1122+
*norm*
1123+
None (optional for :class:`matplotlib.cm.ScalarMappable`)
1124+
*cmap*
1125+
None (optional for :class:`matplotlib.cm.ScalarMappable`)
1126+
1127+
*pickradius* is the tolerance for mouse clicks picking a line.
1128+
The default is 5 pt.
1129+
1130+
The use of :class:`~matplotlib.cm.ScalarMappable` is optional.
1131+
If the :class:`~matplotlib.cm.ScalarMappable` array
1132+
:attr:`~matplotlib.cm.ScalarMappable._A` is not None (ie a call to
1133+
:meth:`~matplotlib.cm.ScalarMappable.set_array` has been made), at
1134+
draw time a call to scalar mappable will be made to set the colors.
1135+
1136+
**Example:**
1137+
1138+
.. plot:: mpl_examples/pylab_examples/eventcollection_demo.py
1139+
"""
1140+
1141+
segment = (lineoffset + linelength / 2.,
1142+
lineoffset - linelength / 2.)
1143+
if len(positions) == 0:
1144+
segments = []
1145+
elif hasattr(positions, 'ndim') and positions.ndim > 1:
1146+
raise ValueError('if positions is an ndarry it cannot have \
1147+
dimensionality great than 1 ')
1148+
elif (orientation is None or orientation.lower() == 'none' or
1149+
orientation.lower() == 'horizontal'):
1150+
positions.sort()
1151+
segments = [[(coord1, coord2) for coord2 in segment] for
1152+
coord1 in positions]
1153+
self._is_horizontal = True
1154+
elif orientation.lower() == 'vertical':
1155+
positions.sort()
1156+
segments = [[(coord2, coord1) for coord2 in segment] for
1157+
coord1 in positions]
1158+
self._is_horizontal = False
1159+
else:
1160+
raise ValueError("orientation must be 'horizontal' or 'vertical'")
1161+
1162+
LineCollection.__init__(self,
1163+
segments,
1164+
linewidths=linewidth,
1165+
colors=color,
1166+
antialiaseds=antialiased,
1167+
linestyles=linestyle,
1168+
**kwargs)
1169+
1170+
self._linelength = linelength
1171+
self._lineoffset = lineoffset
1172+
1173+
def get_positions(self):
1174+
'''
1175+
return an array containing the floating-point values of the positions
1176+
'''
1177+
segments = self.get_segments()
1178+
pos = 0 if self.is_horizontal() else 1
1179+
positions = []
1180+
for segment in segments:
1181+
positions.append(segment[0, pos])
1182+
return positions
1183+
1184+
def set_positions(self, positions):
1185+
'''
1186+
set the positions of the events to the specified value
1187+
'''
1188+
if positions is None or (hasattr(positions, 'len') and
1189+
len(positions) == 0):
1190+
self.set_segments([])
1191+
return
1192+
1193+
lineoffset = self.get_lineoffset()
1194+
linelength = self.get_linelength()
1195+
segment = (lineoffset + linelength / 2.,
1196+
lineoffset - linelength / 2.)
1197+
positions = np.asanyarray(positions)
1198+
positions.sort()
1199+
if self.is_horizontal():
1200+
segments = [[(coord1, coord2) for coord2 in segment] for
1201+
coord1 in positions]
1202+
else:
1203+
segments = [[(coord2, coord1) for coord2 in segment] for
1204+
coord1 in positions]
1205+
self.set_segments(segments)
1206+
1207+
def add_positions(self, position):
1208+
'''
1209+
add one or more events at the specified positions
1210+
'''
1211+
if position is None or (hasattr(position, 'len') and
1212+
len(position) == 0):
1213+
return
1214+
positions = self.get_positions()
1215+
positions = np.hstack([positions, np.asanyarray(position)])
1216+
self.set_positions(positions)
1217+
extend_positions = append_positions = add_positions
1218+
1219+
def is_horizontal(self):
1220+
'''
1221+
True if the eventcollection is horizontal, False if vertical
1222+
'''
1223+
return self._is_horizontal
1224+
1225+
def get_orientation(self):
1226+
'''
1227+
get the orientation of the event line, may be:
1228+
[ 'horizontal' | 'vertical' ]
1229+
'''
1230+
return 'horizontal' if self.is_horizontal() else 'vertical'
1231+
1232+
def switch_orientation(self):
1233+
'''
1234+
switch the orientation of the event line, either from vertical to
1235+
horizontal or vice versus
1236+
'''
1237+
segments = self.get_segments()
1238+
for i, segment in enumerate(segments):
1239+
segments[i] = np.fliplr(segment)
1240+
self.set_segments(segments)
1241+
self._is_horizontal = not self.is_horizontal()
1242+
1243+
def set_orientation(self, orientation=None):
1244+
'''
1245+
set the orientation of the event line
1246+
[ 'horizontal' | 'vertical' | None ]
1247+
defaults to 'horizontal' if not specified or None
1248+
'''
1249+
if (orientation is None or orientation.lower() == 'none' or
1250+
orientation.lower() == 'horizontal'):
1251+
is_horizontal = True
1252+
elif orientation.lower() == 'vertical':
1253+
is_horizontal = False
1254+
else:
1255+
raise ValueError("orientation must be 'horizontal' or 'vertical'")
1256+
1257+
if is_horizontal == self.is_horizontal():
1258+
return
1259+
self.switch_orientation()
1260+
1261+
def get_linelength(self):
1262+
'''
1263+
get the length of the lines used to mark each event
1264+
'''
1265+
return self._linelength
1266+
1267+
def set_linelength(self, linelength):
1268+
'''
1269+
set the length of the lines used to mark each event
1270+
'''
1271+
if linelength == self.get_linelength():
1272+
return
1273+
lineoffset = self.get_lineoffset()
1274+
segments = self.get_segments()
1275+
pos = 1 if self.is_horizontal() else 0
1276+
for segment in segments:
1277+
segment[0, pos] = lineoffset + linelength / 2.
1278+
segment[1, pos] = lineoffset - linelength / 2.
1279+
self.set_segments(segments)
1280+
self._linelength = linelength
1281+
1282+
def get_lineoffset(self):
1283+
'''
1284+
get the offset of the lines used to mark each event
1285+
'''
1286+
return self._lineoffset
1287+
1288+
def set_lineoffset(self, lineoffset):
1289+
'''
1290+
set the offset of the lines used to mark each event
1291+
'''
1292+
if lineoffset == self.get_lineoffset():
1293+
return
1294+
linelength = self.get_linelength()
1295+
segments = self.get_segments()
1296+
pos = 1 if self.is_horizontal() else 0
1297+
for segment in segments:
1298+
segment[0, pos] = lineoffset + linelength / 2.
1299+
segment[1, pos] = lineoffset - linelength / 2.
1300+
self.set_segments(segments)
1301+
self._lineoffset = lineoffset
1302+
1303+
def get_linewidth(self):
1304+
'''
1305+
get the width of the lines used to mark each event
1306+
'''
1307+
return self.get_linewidths()[0]
1308+
1309+
def get_linestyle(self):
1310+
'''
1311+
get the style of the lines used to mark each event
1312+
[ 'solid' | 'dashed' | 'dashdot' | 'dotted' ]
1313+
'''
1314+
return self.get_linestyles()
1315+
1316+
def get_color(self):
1317+
'''
1318+
get the color of the lines used to mark each event
1319+
'''
1320+
return self.get_colors()[0]
1321+
1322+
10711323
class CircleCollection(Collection):
10721324
"""
10731325
A collection of circles, drawn using splines.

0 commit comments

Comments
 (0)
0