Source code for yt.visualization.tick_locators

from __future__ import print_function
##
## This is a modified version of the LogLocator used in Matplotlib.
## It is subject to the terms of the BSD license, and copyright is held by the
## original authors.
##

import math
import numpy as np

if x == 0.0:
return True
lx = math.log(x)/math.log(base)
return lx==int(lx)

[docs]class LogLocator(object):
"""
Determine the tick locations for log axes
"""

def __init__(self, base=10.0, subs=[1.0], numdecs=4):
"""
place ticks on the location= base**i*subs[j]
"""
self.base(base)
self.subs(subs)
self.numticks = 15
self.numdecs = numdecs

[docs]    def base(self,base):
"""
set the base of the log scaling (major tick every base**i, i integer)
"""
self._base=base+0.0

[docs]    def subs(self,subs):
"""
set the minor ticks the log scaling every base**i*subs[j]
"""
if subs is None:
self._subs = None  # autosub
else:
self._subs = np.asarray(subs)+0.0

def _set_numticks(self):
self.numticks = 15  # todo; be smart here; this is just for dev

def __call__(self, vmin, vmax):
'Return the locations of the ticks'
b=self._base

if vmin <= 0.0:
raise ValueError(
"Data has no positive values, and therefore can not be log-scaled.")

vmin = math.log(vmin)/math.log(b)
vmax = math.log(vmax)/math.log(b)

if vmax<vmin:
vmin, vmax = vmax, vmin

numdec = math.floor(vmax)-math.ceil(vmin)

if self._subs is None: # autosub
if numdec>10: subs = np.array([1.0])
elif numdec>6: subs = np.arange(2.0, b, 2.0)
else: subs = np.arange(2.0, b)
else:
subs = self._subs

stride = 1
while numdec/stride+1 > self.numticks:
stride += 1

math.ceil(vmax)+stride, stride)
if len(subs) > 1 or (len(subs == 1) and subs[0] != 1.0):
ticklocs = []
else:

return np.array(ticklocs)

[docs]class LinearLocator(object):
"""
Determine the tick locations

The first time this function is called it will try to set the
number of ticks to make a nice tick partitioning.  Thereafter the
number of ticks will be fixed so that interactive navigation will
be nice
"""

def __init__(self, numticks = None, presets=None):
"""
Use presets to set locs based on lom.  A dict mapping vmin, vmax->locs
"""
self.numticks = numticks
if presets is None:
self.presets = {}
else:
self.presets = presets

def __call__(self, vmin, vmax):
'Return the locations of the ticks'

# vmin, vmax = self.axis.get_view_interval()
# vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05)
if vmax<vmin:
vmin, vmax = vmax, vmin

if (vmin, vmax) in self.presets:
return self.presets[(vmin, vmax)]

if self.numticks is None:
self._set_numticks()

if self.numticks==0: return []
ticklocs = np.linspace(vmin, vmax, self.numticks)

#return self.raise_if_exceeds(ticklocs)
return ticklocs

def _set_numticks(self):
self.numticks = 11  # todo; be smart here; this is just for dev

# def view_limits(self, vmin, vmax):
#     'Try to choose the view limits intelligently'

#     if vmax<vmin:
#         vmin, vmax = vmax, vmin

#     if vmin==vmax:
#         vmin-=1
#         vmax+=1

#     exponent, remainder = divmod(math.log10(vmax - vmin), 1)

#     if remainder < 0.5:
#         exponent -= 1
#     scale = 10**(-exponent)
#     vmin = math.floor(scale*vmin)/scale
#     vmax = math.ceil(scale*vmax)/scale

#     return mtransforms.nonsingular(vmin, vmax)

if __name__ == "__main__":
ll = LogLocator()
print(ll(1e-24, 5e-25))
print(ll(1e-24, 1e-28))
print(ll(1e-24, 1e-35))
lll = LinearLocator()
print(lll(-1e-24, 1e-24))
print(lll(-2.3, 1.3))
print(lll(10,23.))