Skip to content

Commit fcc8039

Browse files
committed
axisartist: implement LocatorDM, LocatorD, LocatorHM, LocatorH and update FormatterHMS and FormaterDMS
1 parent 4ec94bf commit fcc8039

File tree

1 file changed

+175
-70
lines changed

1 file changed

+175
-70
lines changed

lib/mpl_toolkits/axisartist/angle_helper.py

Lines changed: 175 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ def select_step_sub(dv):
9696
return step, factor
9797

9898

99-
def select_step(v1, v2, nv, hour=False, include_last=True):
99+
def select_step(v1, v2, nv, hour=False, include_last=True,
100+
threshold_factor=3600.):
100101

101102
if v1 > v2:
102103
v1, v2 = v2, v1
@@ -111,14 +112,14 @@ def select_step(v1, v2, nv, hour=False, include_last=True):
111112
cycle = 360.
112113

113114
# for degree
114-
if dv > 1./3600.:
115+
if dv > 1./threshold_factor:
115116
#print "degree"
116117
step, factor = _select_step(dv)
117118
else:
118-
step, factor = select_step_sub(dv*3600.)
119+
step, factor = select_step_sub(dv*threshold_factor)
119120
#print "feac", step, factor
120121

121-
factor = factor * 3600.
122+
factor = factor * threshold_factor
122123

123124

124125
f1, f2, fstep = v1*factor, v2*factor, step/factor
@@ -148,81 +149,111 @@ def select_step(v1, v2, nv, hour=False, include_last=True):
148149
return np.array(levs), n, factor
149150

150151

151-
def select_step24(v1, v2, nv, include_last=True):
152+
def select_step24(v1, v2, nv, include_last=True, threshold_factor=3600):
152153
v1, v2 = v1/15., v2/15.
153154
levs, n, factor = select_step(v1, v2, nv, hour=True,
154-
include_last=include_last)
155+
include_last=include_last,
156+
threshold_factor=threshold_factor)
155157
return levs*15., n, factor
156158

157-
def select_step360(v1, v2, nv, include_last=True):
159+
def select_step360(v1, v2, nv, include_last=True, threshold_factor=3600):
158160
return select_step(v1, v2, nv, hour=False,
159-
include_last=include_last)
161+
include_last=include_last,
162+
threshold_factor=threshold_factor)
160163

161164

162165

163-
164-
class LocatorHMS(object):
166+
class LocatorBase(object):
165167
def __init__(self, den, include_last=True):
166168
self.den = den
167169
self._include_last = include_last
170+
171+
def _get_nbins(self):
172+
return self.den
173+
174+
def _set_nbins(self, v):
175+
self.den = v
176+
177+
nbins = property(_get_nbins, _set_nbins)
178+
179+
def set_params(self, **kwargs):
180+
if "nbins" in kwargs:
181+
self.den = int(kwargs.pop("nbins"))
182+
183+
if kwargs:
184+
raise ValueError("Following keys are not processed: %s" % \
185+
", ".join([str(k) for k in kwargs.keys()]))
186+
187+
188+
class LocatorHMS(LocatorBase):
168189
def __call__(self, v1, v2):
169190
return select_step24(v1, v2, self.den, self._include_last)
170191

192+
class LocatorHM(LocatorBase):
193+
def __call__(self, v1, v2):
194+
return select_step24(v1, v2, self.den, self._include_last,
195+
threshold_factor=60)
171196

172-
class LocatorDMS(object):
173-
def __init__(self, den, include_last=True):
174-
self.den = den
175-
self._include_last = include_last
197+
class LocatorH(LocatorBase):
198+
def __call__(self, v1, v2):
199+
return select_step24(v1, v2, self.den, self._include_last,
200+
threshold_factor=1)
201+
202+
203+
class LocatorDMS(LocatorBase):
176204
def __call__(self, v1, v2):
177205
return select_step360(v1, v2, self.den, self._include_last)
178206

207+
class LocatorDM(LocatorBase):
208+
def __call__(self, v1, v2):
209+
return select_step360(v1, v2, self.den, self._include_last,
210+
threshold_factor=60)
179211

180-
class FormatterHMS(object):
181-
def __call__(self, direction, factor, values): # hour
182-
if len(values) == 0:
183-
return []
184-
#ss = [[-1, 1][v>0] for v in values] #not py24 compliant
185-
values = np.asarray(values)
186-
ss = np.where(values>=0, 1, -1)
187-
values = np.abs(values)/15.
212+
class LocatorD(LocatorBase):
213+
def __call__(self, v1, v2):
214+
return select_step360(v1, v2, self.den, self._include_last,
215+
threshold_factor=1)
188216

189-
if factor == 1:
190-
return ["$%s%d^{\mathrm{h}}$" % ({1:"",-1:"-"}[s], int(v),) \
191-
for s, v in zip(ss, values)]
192-
elif factor == 60:
193-
return ["$%d^{\mathrm{h}}\,%02d^{\mathrm{m}}$" % (s*floor(v/60.), v%60) \
194-
for s, v in zip(ss, values)]
195-
elif factor == 3600:
196-
if ss[-1] == -1:
197-
inverse_order = True
198-
values = values[::-1]
199-
else:
200-
inverse_order = False
201-
degree = floor(values[0]/3600.)
202-
hm_fmt = "$%d^{\mathrm{h}}\,%02d^{\mathrm{m}}\,"
203-
s_fmt = "%02d^{\mathrm{s}}$"
204-
l_hm_old = ""
205-
r = []
206-
for v in values-3600*degree:
207-
l_hm = hm_fmt % (ss[0]*degree, floor(v/60.))
208-
l_s = s_fmt % (v%60,)
209-
if l_hm != l_hm_old:
210-
l_hm_old = l_hm
211-
l = l_hm + l_s
212-
else:
213-
l = "$"+l_s
214-
r.append(l)
215-
if inverse_order:
216-
return r[::-1]
217-
else:
218-
return r
219-
#return [fmt % (ss[0]*degree, floor(v/60.), v%60) \
220-
# for s, v in zip(ss, values-3600*degree)]
221-
else: # factor > 3600.
222-
return [r"$%s^{\mathrm{h}}$" % (str(v),) for v in ss*values]
223217

224218

225219
class FormatterDMS(object):
220+
221+
deg_mark = "^{\circ}"
222+
min_mark = "^{\prime}"
223+
sec_mark = "^{\prime\prime}"
224+
225+
fmt_d = "$%d"+deg_mark+"$"
226+
fmt_ds = r"$%d.\!\!"+deg_mark+"%s$"
227+
228+
# %s for signe
229+
fmt_d_m = r"$%s%d"+deg_mark+"\,%02d"+min_mark+"$"
230+
fmt_d_ms = r"$%s%d"+deg_mark+"\,%02d.\mkern-4mu"+min_mark+"%s$"
231+
232+
233+
fmt_d_m_partial = "$%s%d"+deg_mark+"\,%02d"+min_mark+"\,"
234+
fmt_s_partial = "%02d"+sec_mark+"$"
235+
fmt_ss_partial = "%02d.\!\!"+sec_mark+"%s$"
236+
237+
238+
def _get_number_fraction(self, factor):
239+
## check for fractional numbers
240+
number_fraction = None
241+
# check for 60
242+
243+
for threshold in [1, 60, 3600]:
244+
if factor <= threshold:
245+
break
246+
247+
d = factor // threshold
248+
int_log_d = int(floor(math.log10(d)))
249+
if 10**int_log_d == d and d!=1:
250+
number_fraction = int_log_d
251+
factor = factor // 10**int_log_d
252+
return factor, number_fraction
253+
254+
return factor, number_fraction
255+
256+
226257
def __call__(self, direction, factor, values):
227258
if len(values) == 0:
228259
return []
@@ -233,43 +264,88 @@ def __call__(self, direction, factor, values):
233264
sign_map = {(-1, True):"-"}
234265
signs = [sign_map.get((s, v!=0), "") for s, v in zip(ss, values)]
235266

267+
factor, number_fraction = self._get_number_fraction(factor)
268+
236269
values = np.abs(values)
237270

271+
if number_fraction is not None:
272+
values, frac_part = divmod(values, 10**number_fraction)
273+
frac_fmt = "%%0%dd" % (number_fraction,)
274+
frac_str = [frac_fmt % (f1,) for f1 in frac_part]
275+
238276
if factor == 1:
239-
return ["$%d^{\circ}$" % (s*int(v),) for (s, v) in zip(ss, values)]
277+
if number_fraction is None:
278+
return [self.fmt_d % (s*int(v),) for (s, v) in zip(ss, values)]
279+
else:
280+
return [self.fmt_ds % (s*int(v), f1) for (s, v, f1) in \
281+
zip(ss, values, frac_str)]
240282
elif factor == 60:
241-
return ["$%s%d^{\circ}\,%02d^{\prime}$" % (s,floor(v/60.), v%60) \
242-
for s, v in zip(signs, values)]
283+
deg_part, min_part = divmod(values, 60)
284+
if number_fraction is None:
285+
return [self.fmt_d_m % (s1, d1, m1) \
286+
for s1, d1, m1 in zip(signs, deg_part, min_part)]
287+
else:
288+
return [self.fmt_d_ms % (s, d1, m1, f1) \
289+
for s, d1, m1, f1 in zip(signs, deg_part, min_part, frac_str)]
290+
243291
elif factor == 3600:
244292
if ss[-1] == -1:
245293
inverse_order = True
246294
values = values[::-1]
247295
sings = signs[::-1]
248296
else:
249297
inverse_order = False
250-
degree = floor(values[0]/3600.)
251-
hm_fmt = "$%s%d^{\circ}\,%02d^{\prime}\,"
252-
s_fmt = "%02d^{\prime\prime}$"
298+
253299
l_hm_old = ""
254300
r = []
255-
for v, s in zip(values-3600*degree, signs):
256-
l_hm = hm_fmt % (s, degree, floor(v/60.))
257-
l_s = s_fmt % (v%60,)
301+
302+
deg_part, min_part_ = divmod(values, 3600)
303+
min_part, sec_part = divmod(min_part_, 60)
304+
305+
if number_fraction is None:
306+
sec_str = [self.fmt_s_partial % (s1,) for s1 in sec_part]
307+
else:
308+
sec_str = [self.fmt_ss_partial % (s1, f1) for s1, f1 in zip(sec_part, frac_str)]
309+
310+
for s, d1, m1, s1 in zip(signs, deg_part, min_part, sec_str):
311+
l_hm = self.fmt_d_m_partial % (s, d1, m1)
258312
if l_hm != l_hm_old:
259313
l_hm_old = l_hm
260-
l = l_hm + l_s
314+
l = l_hm + s1 #l_s
261315
else:
262-
l = "$"+l_s
316+
l = "$"+s1 #l_s
263317
r.append(l)
318+
264319
if inverse_order:
265320
return r[::-1]
266321
else:
267322
return r
268-
#return [fmt % (ss[0]*degree, floor(v/60.), v%60) \
269-
# for s, v in zip(ss, values-3600*degree)]
323+
270324
else: # factor > 3600.
271325
return [r"$%s^{\circ}$" % (str(v),) for v in ss*values]
272326

327+
class FormatterHMS(FormatterDMS):
328+
deg_mark = "^{\mathrm h}"
329+
min_mark = "^{\mathrm m}"
330+
sec_mark = "^{\mathrm s}"
331+
332+
fmt_d = "$%d"+deg_mark+"$"
333+
fmt_ds = r"$%d.\!\!"+deg_mark+"%s$"
334+
335+
# %s for signe
336+
fmt_d_m = r"$%s%d"+deg_mark+"\,%02d"+min_mark+"$"
337+
fmt_d_ms = r"$%s%d"+deg_mark+"\,%02d.\!\!"+min_mark+"%s$"
338+
339+
340+
fmt_d_m_partial = "$%s%d"+deg_mark+"\,%02d"+min_mark+"\,"
341+
fmt_s_partial = "%02d"+sec_mark+"$"
342+
fmt_ss_partial = "%02d.\!\!"+sec_mark+"%s$"
343+
344+
345+
def __call__(self, direction, factor, values): # hour
346+
return FormatterDMS.__call__(self, direction, factor, np.asarray(values)/15.)
347+
348+
273349

274350

275351

@@ -352,11 +428,40 @@ def _adjust_extremes(self, lon_min, lon_max, lat_min, lat_max):
352428

353429
if __name__ == "__main__":
354430
#test2()
355-
print select_step360(21.2, 33.3, 5)
431+
#print select_step360(21.2, 33.3, 5)
432+
#print select_step360(20+21.2/60., 21+33.3/60., 5)
433+
#print select_step360(20.5+21.2/3600., 20.5+33.3/3600., 5)
434+
435+
# test threshold factor
436+
print select_step360(20.5+11.2/3600., 20.5+53.3/3600., 5,
437+
threshold_factor=60)
438+
439+
print select_step360(20.5+11.2/3600., 20.5+53.3/3600., 5,
440+
threshold_factor=1)
441+
442+
fmt = FormatterDMS()
443+
#print fmt("left", 60, [0, -30, -60])
444+
print fmt("left", 600, [12301, 12302, 12303])
445+
446+
print select_step360(20.5+21.2/3600., 20.5+21.4/3600., 5)
447+
print fmt("left", 36000, [738210, 738215, 738220])
448+
print fmt("left", 360000, [7382120, 7382125, 7382130])
449+
print fmt("left", 1., [45, 46, 47])
450+
print fmt("left", 10., [452, 453, 454])
451+
452+
if 0:
356453
print select_step360(20+21.2/60., 21+33.3/60., 5)
357454
print select_step360(20.5+21.2/3600., 20.5+33.3/3600., 5)
358455
print select_step360(20+21.2/60., 20+53.3/60., 5)
359456

457+
###
458+
levs, n, factor = select_step360(20.5+21.2/3600., 20.5+27.25/3600., 5)
459+
levs = levs * 0.1
460+
fmt = FormatterDMS()
461+
#print fmt("left", 60, [0, -30, -60])
462+
print fmt("left", factor, levs)
463+
464+
360465
print select_step(-180, 180, 10, hour=False)
361466
print select_step(-12, 12, 10, hour=True)
362467

0 commit comments

Comments
 (0)