@@ -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
225219class 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
353429if __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