angle_helper.py :  » Chart-Report » Matplotlib » matplotlib-0.99.1.1 » lib » mpl_toolkits » axes_grid » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Chart Report » Matplotlib 
Matplotlib » matplotlib 0.99.1.1 » lib » mpl_toolkits » axes_grid » angle_helper.py
from math import floor

import numpy as np
import math

A = np.array

from mpl_toolkits.axes_grid.grid_finder import ExtremeFinderSimple

def select_step_degree(dv):

    degree_limits_ = [1.5, 3, 7, 13, 20, 40, 70, 120, 270, 520]
    degree_steps_  = [  1, 2, 5, 10, 15, 30, 45,  90, 180, 360]
    degree_factors = [1.] * len(degree_steps_)

    minsec_limits_ = [1.5, 2.5, 3.5, 8, 11, 18, 25, 45]
    minsec_steps_  = [1,   2,   3,   5, 10, 15, 20, 30]

    minute_limits_ = A(minsec_limits_)*(1./60.)
    minute_factors = [60.] * len(minute_limits_)

    second_limits_ = A(minsec_limits_)*(1./3600.)
    second_factors = [3600.] * len(second_limits_)

    degree_limits = np.concatenate([second_limits_,
                                    minute_limits_,
                                    degree_limits_])

    degree_steps = np.concatenate([minsec_steps_,
                                   minsec_steps_,
                                   degree_steps_])

    degree_factors = np.concatenate([second_factors,
                                     minute_factors,
                                     degree_factors])

    n = degree_limits.searchsorted(dv)
    step = degree_steps[n]
    factor = degree_factors[n]

    return step, factor



def select_step_hour(dv):

    hour_limits_ = [1.5, 2.5, 3.5, 5, 7, 10, 15, 21, 36]
    hour_steps_  = [1,   2  , 3,   4, 6,  8, 12, 18, 24]
    hour_factors = [1.] * len(hour_steps_)

    minsec_limits_ = [1.5, 2.5, 3.5, 4.5, 5.5, 8, 11, 14, 18, 25, 45]
    minsec_steps_  = [1,   2,   3,   4,   5,   6, 10, 12, 15, 20, 30]

    minute_limits_ = A(minsec_limits_)*(1./60.)
    minute_factors = [60.] * len(minute_limits_)

    second_limits_ = A(minsec_limits_)*(1./3600.)
    second_factors = [3600.] * len(second_limits_)

    hour_limits = np.concatenate([second_limits_,
                                  minute_limits_,
                                  hour_limits_])

    hour_steps = np.concatenate([minsec_steps_,
                                 minsec_steps_,
                                 hour_steps_])

    hour_factors = np.concatenate([second_factors,
                                   minute_factors,
                                   hour_factors])

    n = hour_limits.searchsorted(dv)
    step = hour_steps[n]
    factor = hour_factors[n]

    return step, factor


def select_step_sub(dv):

    # subarcsec or degree
    tmp = 10.**(int(math.log10(dv))-1.)
    dv2 = dv/tmp
    substep_limits_ = [1.5, 3., 7.]
    substep_steps_  = [1. , 2., 5.]

    factor = 1./tmp

    if 1.5*tmp >= dv:
        step = 1
    elif 3.*tmp >= dv:
        step = 2
    elif 7.*tmp >= dv:
        step = 5
    else:
        step = 1
        factor = 0.1*factor

    return step, factor


def select_step(v1, v2, nv, hour=False):

    if v1 > v2:
        v1, v2 = v2, v1

    A = np.array

    dv = float(v2 - v1) / nv

    if hour:
        _select_step = select_step_hour
        cycle = 24.
    else:
        _select_step = select_step_degree
        cycle = 360.

    # for degree
    if dv > 1./3600.:
        #print "degree"
        step, factor = _select_step(dv)
    else:
        step, factor = select_step_sub(dv*3600.)
        #print "feac", step, factor

        factor = factor * 3600.


    f1, f2, fstep = v1*factor, v2*factor, step/factor
    levs = np.arange(math.floor(f1/step), math.ceil(f2/step)+0.5,
                     1, dtype="i") * step

    # n : number valid levels. If there is a cycle, e.g., [0, 90, 180,
    # 270, 360], the a grid line needs to be extend from 0 to 360, so
    # we need to return the whole array. However, the last level (360)
    # needs to be ignored often. In this case, so we return n=4.

    n = len(levs)


    # we need to check the range of values
    # for example, -90 to 90, 0 to 360,


    if factor == 1. and (levs[-1] >= levs[0]+cycle): # check for cycle
        nv = int(cycle / step)
        levs = np.arange(0, nv, 1) * step
        n = len(levs)

    return levs, n, factor


def select_step24(v1, v2, nv):
    v1, v2 = v1/15., v2/15.
    levs, n, factor =  select_step(v1, v2, nv, hour=True)
    return levs*15., n, factor

def select_step360(v1, v2, nv):
    return select_step(v1, v2, nv, hour=False)




class LocatorHMS(object):
    def __init__(self, den):
        self.den = den
    def __call__(self, v1, v2):
        return select_step24(v1, v2, self.den)


class LocatorDMS(object):
    def __init__(self, den):
        self.den = den
    def __call__(self, v1, v2):
        return select_step360(v1, v2, self.den)


class FormatterHMS(object):
    def __call__(self, direction, factor, values): # hour
        if len(values) == 0:
            return []
        ss = [[-1, 1][v>0] for v in values]
        values = np.abs(values)/15.

        if factor == 1:
            return ["$%d^{\mathrm{h}}$" % (int(v),) for v in values]
        elif factor == 60:
            return ["$%d^{\mathrm{h}}\,%02d^{\mathrm{m}}$" % (s*floor(v/60.), v%60) \
                    for s, v in zip(ss, values)]
        elif factor == 3600:
            if ss[-1] == -1:
                inverse_order = True
                values = values[::-1]
            else:
                inverse_order = False
            degree = floor(values[0]/3600.)
            hm_fmt = "$%d^{\mathrm{h}}\,%02d^{\mathrm{m}}\,"
            s_fmt = "%02d^{\mathrm{s}}$"
            l_hm_old = ""
            r = []
            for v in values-3600*degree:
                l_hm = hm_fmt % (ss[0]*degree, floor(v/60.))
                l_s = s_fmt % (v%60,)
                if l_hm != l_hm_old:
                    l_hm_old = l_hm
                    l = l_hm + l_s
                else:
                    l = "$"+l_s
                r.append(l)
            if inverse_order:
                return r[::-1]
            else:
                return r
        #return [fmt % (ss[0]*degree, floor(v/60.), v%60) \
        #        for s, v in zip(ss, values-3600*degree)]
        else: # factor > 3600.
            return ["$%s$" % (str(v),) for v in values]


class FormatterDMS(object):
    def __call__(self, direction, factor, values):
        if len(values) == 0:
            return []
        ss = [[-1, 1][v>0] for v in values]
        values = np.abs(values)
        if factor == 1:
            return ["$%d^{\circ}$" % (s*int(v),) for (s, v) in zip(ss, values)]
        elif factor == 60:
            return ["$%d^{\circ}\,%02d^{\prime}$" % (s*floor(v/60.), v%60) \
                    for s, v in zip(ss, values)]
        elif factor == 3600:
            if ss[-1] == -1:
                inverse_order = True
                values = values[::-1]
            else:
                inverse_order = False
            degree = floor(values[0]/3600.)
            hm_fmt = "$%d^{\circ}\,%02d^{\prime}\,"
            s_fmt = "%02d^{\prime\prime}$"
            l_hm_old = ""
            r = []
            for v in values-3600*degree:
                l_hm = hm_fmt % (ss[0]*degree, floor(v/60.))
                l_s = s_fmt % (v%60,)
                if l_hm != l_hm_old:
                    l_hm_old = l_hm
                    l = l_hm + l_s
                else:
                    l = "$"+l_s
                r.append(l)
            if inverse_order:
                return r[::-1]
            else:
                return r
            #return [fmt % (ss[0]*degree, floor(v/60.), v%60) \
            #        for s, v in zip(ss, values-3600*degree)]
        else: # factor > 3600.
            return ["$%s$" % (str(v),) for v in ss*values]




class ExtremeFinderCycle(ExtremeFinderSimple):
    """
    When there is a cycle, e.g., longitude goes from 0-360.
    """
    def __init__(self,
                 nx, ny,
                 lon_cycle = 360.,
                 lat_cycle = None,
                 lon_minmax = None,
                 lat_minmax = (-90, 90)
                 ):
        #self.transfrom_xy = transform_xy
        #self.inv_transfrom_xy = inv_transform_xy
        self.nx, self.ny = nx, ny
        self.lon_cycle, self.lat_cycle = lon_cycle, lat_cycle
        self.lon_minmax = lon_minmax
        self.lat_minmax = lat_minmax


    def __call__(self, transform_xy, x1, y1, x2, y2):
        """
        get extreme values.

        x1, y1, x2, y2 in image coordinates (0-based)
        nx, ny : number of dvision in each axis
        """
        x_, y_ = np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny)
        x, y = np.meshgrid(x_, y_)
        lon, lat = transform_xy(np.ravel(x), np.ravel(y))

        # iron out jumps, but algorithm should be improved.
        # Tis is just naive way of doing and my fail for some cases.
        if self.lon_cycle is not None:
            lon0 = np.nanmin(lon)
            lon -= 360. * ((lon - lon0) > 180.)
        if self.lat_cycle is not None:
            lat0 = np.nanmin(lat)
            lat -= 360. * ((lat - lat0) > 180.)

        lon_min, lon_max = np.nanmin(lon), np.nanmax(lon)
        lat_min, lat_max = np.nanmin(lat), np.nanmax(lat)

        lon_min, lon_max, lat_min, lat_max = \
                 self._adjust_extremes(lon_min, lon_max, lat_min, lat_max)

        return lon_min, lon_max, lat_min, lat_max


    def _adjust_extremes(self, lon_min, lon_max, lat_min, lat_max):

        lon_min, lon_max, lat_min, lat_max = \
                 self._add_pad(lon_min, lon_max, lat_min, lat_max)

        # check cycle
        if self.lon_cycle:
            lon_max = min(lon_max, lon_min + self.lon_cycle)
        if self.lat_cycle:
            lat_max = min(lat_max, lat_min + self.lat_cycle)

        if self.lon_minmax is not None:
            min0 = self.lon_minmax[0]
            lon_min = max(min0, lon_min)
            max0 = self.lon_minmax[1]
            lon_max = min(max0, lon_max)

        if self.lat_minmax is not None:
            min0 = self.lat_minmax[0]
            lat_min = max(min0, lat_min)
            max0 = self.lat_minmax[1]
            lat_max = min(max0, lat_max)

        return lon_min, lon_max, lat_min, lat_max





if __name__ == "__main__":
    #test2()
    print select_step360(21.2, 33.3, 5)
    print select_step360(20+21.2/60., 21+33.3/60., 5)
    print select_step360(20.5+21.2/3600., 20.5+33.3/3600., 5)
    print select_step360(20+21.2/60., 20+53.3/60., 5)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.