1
2
3 import Num
4 import math
5
6
9 self._xc = xc
10 self._yc = yc
11 self._xw = xw
12 self._yw = yw
13
15 return self._xc - self._xw/2.0
16
18 return self._xc + self._xw/2.0
19
21 return self._yc - self._yw/2.0
22
24 return self._yc + self._yw/2.0
25
28
31
34
37
39 return boxc(self._xc+x, self._yc+y, self._xw, self._yw)
40
41
42 -class text_template(object):
43 - def __init__(self, text, H, W):
44 """(0,0) is the lower left corner of the block of text."""
45 self.lines = []
46 self.txt = []
47 la = text.split('\n')
48 n = len(la)
49 for (i, l) in enumerate(la):
50 self.addline(0.0, H*(n-1-i), W*len(l), H, l)
51
52 - def addline(self, x0, y0, xlength, yht, txtline):
53 """Specify LLC."""
54 self.lines.append(boxc(x0+xlength/2.0, y0+yht/2.0,
55 xlength, yht)
56 )
57 self.txt.append(txtline)
58
60 return len(self.lines)
61
62
66
68 arg = (y-ybar)**2/(2*yvar)
69 return math.exp(-arg)/math.sqrt(2*math.pi*yvar)
70
72 return gauss(y, ybar, yvar) - 0.3*gauss(y, ybar, 40*yvar)
73
74
75
77 - def __init__(self, fracCharHt, fracCharW, xmin, xmax, ymin, ymax):
78 self.H = fracCharHt
79 self.W = fracCharW
80 self.datasets = []
81 self.avoidlist = []
82 boxc.__init__(self, xmin, ymin, xmax-xmin, ymax-ymin)
83 self.YN = 100
84 self.DF = 10.0
85
86
89
90
91 - def _fom_y(self, ycand, x0, relbox):
92 rlist = []
93 xtra_var = self.h()**2 * ((1.0/self.YN)**2 + self.H**2)
94 xbdr = self.h() * self.H
95 for (x, y) in self.datasets :
96 ovlap = Num.greater(x, x0+relbox.xmin()-xbdr) * Num.less(x, x0+relbox.xmax()+xbdr)
97 avoid = Num.compress(ovlap, y)
98 an = avoid.shape[0]
99 if an > 1:
100 asum = Num.sum(avoid, axis=0)
101 assq = Num.sum((avoid-asum/an)**2, axis=0)
102 assq += an * xtra_var
103
104 rlist.append( (asum/an, assq/an, -self.DF) )
105
106 rlist.append( (asum/an, 100.0*assq/an, 0.1*self.DF) )
107
108 rn = y.shape[0]
109 if rn > 1:
110 rsum = Num.sum(y, axis=0)
111 rssq = Num.sum((y-rsum/rn)**2, axis=0)
112 rssq += rn * xtra_var
113
114 rlist.append( (rsum/rn, 2*rssq/rn, 0.1*self.DF) )
115
116 for a in self.avoidlist:
117 veff = relbox.w()**2 + a.w()**2
118 wt = q_gauss(x0+relbox.xc(), a.xc(), veff)
119 rlist.append( (a.yc(), a.h()**2, -wt) )
120
121 fom = Num.zeros(ycand.shape, Num.Float)
122 yco = ycand + relbox.ymin()
123 for (rbar, rvar, wt) in rlist:
124 fom += wt*Gauss(yco, rbar, rvar+relbox.h()**2)
125 return fom
126
128 """Figures out a good place to put a label.
129 The label is at a specified tc, but can be at any vertical
130 position. This finds a good vertical position.
131 Returns the bottom of the block of text.
132 """
133 delta = self.h()/self.YN
134 y_candidates = (Num.arrayrange(self.YN)-(0.5*self.YN))*delta + self.yc()
135 fom = Num.zeros(y_candidates.shape, Num.Float)
136 for lbox in ttm.lines:
137 tmp = self._fom_y(y_candidates, x0, lbox)
138 Num.add(fom, tmp, fom)
139 return y_candidates[Num.argmax(fom)]
140
141
142 - def textplace(self, x0, text):
143 tt = text_template(text, self.H*self.h(), self.W*self.w())
144 yc = self.find_y( x0, tt )
145 for (l, bx) in zip(tt.txt, tt.lines):
146 bxs = bx.shift(x0, yc)
147 self.avoidlist.append(bxs)
148 yield (bxs.xmin(), bxs.ymin(), l)
149
150
154