Skip to content

Commit

Permalink
Default to base-2 minor breaks for log tranforms
Browse files Browse the repository at this point in the history
  • Loading branch information
has2k1 committed Dec 24, 2018
1 parent 48a3224 commit 48e3fd8
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
12 changes: 12 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
Changelog
=========

v0.5.3
------
*(not-yet-released)*

API Changes
-----------
- Log transforms now default to ``base - 2`` minor breaks.
So base 10 has 8 minor breaks and 9 partitions,
base 8 has 6 minor breaks and 7 partitions, ...,
base 2 has 0 minor breaks and a single partition.


v0.5.2
------
*(2018-17-10)*
Expand Down
15 changes: 14 additions & 1 deletion mizani/tests/test_breaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from mizani.breaks import (mpl_breaks, log_breaks, minor_breaks,
trans_minor_breaks, date_breaks,
timedelta_breaks, extended_breaks)
from mizani.transforms import trans
from mizani.transforms import trans, log_trans


def test_mpl_breaks():
Expand Down Expand Up @@ -130,6 +130,19 @@ def __init__(self):
with pytest.raises(TypeError):
t.minor_breaks(major)

# Test minor_breaks for log scales are 2 less than the base
base = 10
breaks = np.arange(1, 3)
limits = [breaks[0], breaks[-1]]
t = log_trans(base)
assert len(t.minor_breaks(breaks, limits)) == base - 2

base = 5 # Odd base
breaks = np.arange(1, 3)
limits = [breaks[0], breaks[-1]]
t = log_trans(base)
assert len(t.minor_breaks(breaks, limits)) == base - 2


def test_date_breaks():
# cpython
Expand Down
8 changes: 7 additions & 1 deletion mizani/tests/test_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,19 @@ def _test_trans(trans, x):
t = gettrans(trans())
xt = t.transform(x)
x2 = t.inverse(xt)
is_log_trans = (t.__class__.__name__.startswith('log') and
hasattr(t, 'base'))
# round trip
npt.assert_allclose(x, x2)
major = t.breaks([min(x), max(x)])
minor = t.minor_breaks(t.transform(major))
# Breaks and they are finite
assert len(major)
assert len(minor)
if is_log_trans and int(t.base) == 2:
# Minor breaks for base == 2
assert len(minor) == 0
else:
assert len(minor)
assert all(np.isfinite(major))
assert all(np.isfinite(minor))
# Not breaks outside the domain
Expand Down
14 changes: 11 additions & 3 deletions mizani/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def breaks(self, limits):

def trans_new(name, transform, inverse, breaks=None,
minor_breaks=None, _format=None,
domain=(-np.inf, np.inf), doc=''):
domain=(-np.inf, np.inf), doc='', **kwargs):
"""
Create a transformation class object
Expand Down Expand Up @@ -198,6 +198,9 @@ def trans_new(name, transform, inverse, breaks=None,
It should be of length 2.
doc : str
Docstring for the class.
**kwargs : dict
Attributes of the transform, e.g if base is passed
in kwargs, then `t.base` would be a valied attribute.
Returns
-------
Expand All @@ -215,7 +218,8 @@ def _get(func):
d = {'transform': _get(transform),
'inverse': _get(inverse),
'domain': domain,
'__doc__': doc}
'__doc__': doc,
**kwargs}

if breaks:
d['breaks_'] = _get(breaks)
Expand Down Expand Up @@ -278,12 +282,14 @@ def inverse(x):
if 'breaks' not in kwargs:
kwargs['breaks'] = log_breaks(base=base)

kwargs['base'] = base
kwargs['_format'] = log_format(base)

_trans = trans_new(name, transform, inverse, **kwargs)

if 'minor_breaks' not in kwargs:
_trans.minor_breaks = trans_minor_breaks(_trans, 4)
n = int(base) - 2
_trans.minor_breaks = trans_minor_breaks(_trans, n=n)

return _trans

Expand Down Expand Up @@ -327,6 +333,7 @@ def transform(x):
def inverse(x):
return np.log(x)/np.log(base)

kwargs['base'] = base
return trans_new(name, transform, inverse, **kwargs)


Expand Down Expand Up @@ -406,6 +413,7 @@ def transform(x):
def inverse(x):
return (np.abs(x) * p + np.sign(x)) ** (1 / p)

kwargs['p'] = p
kwargs['name'] = kwargs.get('name', 'pow_{}'.format(p))
kwargs['transform'] = transform
kwargs['inverse'] = inverse
Expand Down

0 comments on commit 48e3fd8

Please sign in to comment.