-
Notifications
You must be signed in to change notification settings - Fork 4
/
Label.py
141 lines (107 loc) · 3.77 KB
/
Label.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from matplotlib import pyplot
from PlotInfo import PlotInfo
from Marker import Marker
from LabelProperties import LabelProperties
class Label(PlotInfo):
"""
Labels a point on the plot with text and/or arrows
"""
def __init__(self, x, y, text=None, bbox=None):
PlotInfo.__init__(self, "label")
self.x = x
"""
The label's x coordinate
"""
self.y = y
"""
The label's y coordinate
"""
self.text = text
"""
The text that should be displayed with the label
"""
self.textX = x
self.textY = y
self.arrow = None
self._marker = Marker()
self._labelProperties = LabelProperties()
if bbox:
self.bbox = dict(bbox)
else:
self.bbox = None
@property
def marker(self):
"""
The marker type that should be used to mark the labeled point
"""
return self._marker.marker
@marker.setter
def marker(self, value):
self._marker.marker = value
@property
def textOffset(self):
return (self.textX - self.x, self.textY - self.y)
@textOffset.setter
def textOffset(self, offset):
if type(offset) not in [tuple, list] or len(offset) != 2:
raise AttributeError, "Expected a two-element tuple when " \
"setting textOffset"
self.setTextOffset(offset[0], offset[1])
def setTextOffset(self, x, y):
self.textX = self.x + x
self.textY = self.y + y
@property
def textPosition(self):
return (self.textX, self.textY)
@textPosition.setter
def textPosition(self, pos):
if type(pos) not in [tuple, list] or len(pos) != 2:
raise AttributeError, "Expected a two-element tuple when " \
"setting textOffset"
self.setTextPosition(pos[0], pos[1])
def setTextPosition(self, x, y):
self.textX = x
self.textY = y
@property
def labelProperties(self):
"""
A dictionary of properties that control the appearance of the label. See
:ref:`styling-labels` for more information on which properties can be
set.
"""
return self._labelProperties
@labelProperties.setter
def labelProperties(self, propsobj):
self.labelProperties.update(propsobj)
@property
def rotation(self):
return self._labelProperties["rotation"]
@rotation.setter
def rotation(self, value):
self._labelProperties["rotation"] = value
def hasArrow(self, style="->", color="black"):
"""
Defines an arrow between the label's text and its point. Valid arrow
styles are given in `Matplotlib's documentation <http://matplotlib.github.com/users/annotations_guide.html?highlight=arrowprops#annotating-with-arrow>`_.
"""
self.arrow = dict(facecolor=color, arrowstyle=style)
def draw(self, fig, axis, transform=None):
kwdict = {}
kwdict["xytext"] = (self.textX, self.textY)
kwdict["xycoords"] = "data"
kwdict["textcoords"] = "data"
kwdict["arrowprops"] = self.arrow
kwdict["horizontalalignment"] = "center"
kwdict.update(self.labelProperties)
# For props, see
# http://matplotlib.sourceforge.net/api/artist_api.html#matplotlib.patches.Rectangle
if self.bbox: kwdict["bbox"] = self.bbox
handles = []
labels = []
handles.append(axis.annotate(self.text, (self.x, self.y), **kwdict))
labels.append(None)
if self.marker is not None:
handles.append(axis.scatter([self.x],[self.y],marker=self.marker,
color="black"))
labels.append(None)
return [handles, labels]