Skip to content

Commit

Permalink
Fix log_breaks and log_format
Browse files Browse the repository at this point in the history
  • Loading branch information
has2k1 committed Oct 15, 2018
1 parent 1f94c2b commit ab833e5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
19 changes: 19 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
Changelog
=========

v0.5.1
------
*(2018-15-10)*

Bug Fixes
*********

- Fixed issue with :class:`~mizani.breaks.log_breaks`, so that it does
not fail needlessly when the limits in the (0, 1) range.

Enhancements
************

- Changed :class:`~mizani.formatters.log_format` to return better
formatted breaks.

v0.5.0
------
*(2018-11-10)*

.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.62319878.svg
:target: https://doi.org/10.5281/zenodo.62319878

API Changes
***********

Expand Down
11 changes: 9 additions & 2 deletions mizani/breaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class log_breaks:
array([ 100, 1000, 10000, 100000, 1000000])
>>> log_breaks(2)(limits)
array([ 100, 100000])
>>> log_breaks()([0.1, 1])
array([0.1, 0.3, 1. , 3. ])
"""

def __init__(self, n=5, base=10):
Expand Down Expand Up @@ -139,6 +141,10 @@ def __call__(self, limits):
_min = int(np.floor(rng[0]))
_max = int(np.ceil(rng[1]))

# numpy arrays with -ve number(s) and of dtype=int
# cannot be powers i.e. base ** arr fails
dtype = float if _min < 0 or _max < 0 else int

if _max == _min:
return base ** _min

Expand All @@ -148,7 +154,7 @@ def __call__(self, limits):
# _log_sub_breaks
by = int(np.floor((_max-_min)/n)) + 1
for step in range(by, 0, -1):
breaks = base ** np.arange(_min, _max+1, step=step)
breaks = base ** np.arange(_min, _max+1, step=step, dtype=dtype)
relevant_breaks = (
(limits[0] <= breaks) &
(breaks <= limits[1])
Expand Down Expand Up @@ -189,6 +195,7 @@ def __call__(self, limits):
rng = np.log(limits)/np.log(base)
_min = int(np.floor(rng[0]))
_max = int(np.ceil(rng[1]))
dtype = float if _min < 0 or _max < 0 else int
steps = [1]

def delta(x):
Expand Down Expand Up @@ -216,7 +223,7 @@ def delta(x):
candidate = np.delete(candidate, best)

breaks = np.outer(
base ** np.arange(_min, _max+1), steps).ravel()
base ** np.arange(_min, _max+1, dtype=dtype), steps).ravel()
relevant_breaks = (
(limits[0] <= breaks) & (breaks <= limits[1]))

Expand Down
21 changes: 17 additions & 4 deletions mizani/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,23 +442,36 @@ def __call__(self, x):
out : list
List of strings.
"""
def _as_integers(x):
"""
Try converting all numbers to integers
"""
nums = [np.round(i, 11) for i in x]
if np.all([float(i).is_integer() for i in nums]):
return [int(i) for i in nums]
return x

if len(x) == 0:
return []

x = _as_integers(x)

# Decide on using exponents
if self.base == 10:
# Order of magnitude of the minimum and maximum
dmin = np.log(np.min(x))/np.log(self.base)
dmax = np.log(np.max(x))/np.log(self.base)
if same_log10_order_of_magnitude((dmin, dmax)):
return mpl_format()(x)

all_multiples = np.all(
[np.log10(num).is_integer() for num in x])
has_small_number = dmin < -3
has_large_number = dmax > 3
has_large_range = (dmax - dmin) > self.exponent_threshold
use_exponent = (has_small_number or
has_large_number or
has_large_range)
use_exponent = (all_multiples and
(has_small_number or
has_large_number or
has_large_range))
else:
use_exponent = False
return [self._format_num(num, use_exponent) for num in x]
Expand Down
7 changes: 3 additions & 4 deletions mizani/tests/test_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,10 @@ def test_log_format():
assert formatter([0.001, 0.1, 1000]) == ['1e-3', '1e-1', '1e3']
assert formatter([35, 60]) == ['35', '60']
assert formatter([34.99999999999, 60.0000000001]) == ['35', '60']
assert formatter([3000.0000000000014, 4999.999999999999]) == \
['3000', '5000']
assert formatter([1, 35, 60, 1000]) == ['1', '35', '60', '1000']
assert formatter([1, 35, 60, 10000]) == ['1', '', '', '1e4']

formatter = log_format()
assert formatter([1, 35, 60, 10000]) == ['1', '', '', '1e4']
assert formatter([1, 35, 60, 10000]) == ['1', '35', '60', '10000']

formatter = log_format(base=2)
assert formatter([1, 10, 11, 1011]) == ['1', '10', '11', '1011']
Expand Down

0 comments on commit ab833e5

Please sign in to comment.