Hello community,

here is the log from the commit of package python-mizani for openSUSE:Factory 
checked in at 2020-07-10 15:30:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-mizani (Old)
 and      /work/SRC/openSUSE:Factory/.python-mizani.new.3060 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-mizani"

Fri Jul 10 15:30:59 2020 rev:2 rq:819927 version:0.7.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-mizani/python-mizani.changes      
2019-12-04 14:20:36.714449861 +0100
+++ /work/SRC/openSUSE:Factory/.python-mizani.new.3060/python-mizani.changes    
2020-07-10 15:31:01.210850437 +0200
@@ -1,0 +2,11 @@
+Fri Jul 10 09:01:26 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- Update to version 0.7.1
+  * Fixed issue with :class:`mizani.formatters.log_breaks` where non-linear 
+    breaks could not be generated if the limits where greater than the largest 
+    integer sys.maxsize.
+  * Fixed :func:`mizani.palettes.gradient_n_pal` to return nan for nan values.
+  * Fixed :func:`mizani.scales.scale_discrete.train` when training 
categoricals 
+    to maintain the order.
+
+-------------------------------------------------------------------

Old:
----
  mizani-0.6.0.tar.gz

New:
----
  mizani-0.7.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-mizani.spec ++++++
--- /var/tmp/diff_new_pack.ABTqkT/_old  2020-07-10 15:31:02.038853161 +0200
+++ /var/tmp/diff_new_pack.ABTqkT/_new  2020-07-10 15:31:02.042853174 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-mizani
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define         skip_python2 1
 Name:           python-mizani
-Version:        0.6.0
+Version:        0.7.1
 Release:        0
 Summary:        Scales for Python
 License:        BSD-3-Clause
@@ -49,6 +49,8 @@
 
 %prep
 %setup -q -n mizani-%{version}
+# correct np.timedelta64 usage
+sed -i 's/unit=//' mizani/tests/test_*.py
 
 %build
 %python_build

++++++ mizani-0.6.0.tar.gz -> mizani-0.7.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/PKG-INFO new/mizani-0.7.1/PKG-INFO
--- old/mizani-0.6.0/PKG-INFO   2019-08-15 14:38:39.000000000 +0200
+++ new/mizani-0.7.1/PKG-INFO   2020-06-05 00:46:54.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: mizani
-Version: 0.6.0
+Version: 0.7.1
 Summary: Scales for Python
 Home-page: https://github.com/has2k1/mizani
 Maintainer: Hassan Kibirige
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/_version.py 
new/mizani-0.7.1/mizani/_version.py
--- old/mizani-0.6.0/mizani/_version.py 2019-08-15 14:38:39.000000000 +0200
+++ new/mizani-0.7.1/mizani/_version.py 2020-06-05 00:46:54.000000000 +0200
@@ -8,11 +8,11 @@
 
 version_json = '''
 {
- "date": "2019-08-15T15:19:49+0300",
+ "date": "2020-06-04T23:24:33+0300",
  "dirty": false,
  "error": null,
- "full-revisionid": "c67e3665f71b7961c97fc24e2940ec47e3724693",
- "version": "0.6.0"
+ "full-revisionid": "e1eb9b2bd362f0462156a3b114585d1c037072ca",
+ "version": "0.7.1"
 }
 '''  # END VERSION_JSON
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/bounds.py 
new/mizani-0.7.1/mizani/bounds.py
--- old/mizani-0.6.0/mizani/bounds.py   2019-06-05 12:50:34.000000000 +0200
+++ new/mizani-0.7.1/mizani/bounds.py   2020-06-03 21:48:57.000000000 +0200
@@ -349,7 +349,9 @@
         finite = np.repeat(True, len(x))
 
     if hasattr(x, 'dtype'):
-        outside = (x < range[0]) | (x > range[1])
+        # Ignore RuntimeWarning when x contains nans
+        with np.errstate(invalid='ignore'):
+            outside = (x < range[0]) | (x > range[1])
         bool_idx = finite & outside
         x = x.copy()
         x[bool_idx] = null
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/breaks.py 
new/mizani-0.7.1/mizani/breaks.py
--- old/mizani-0.6.0/mizani/breaks.py   2019-07-10 13:51:46.000000000 +0200
+++ new/mizani-0.7.1/mizani/breaks.py   2020-06-04 01:20:45.000000000 +0200
@@ -10,6 +10,8 @@
 breaks make interpretation straight forward. These functions
 provide ways to calculate good(hopefully) breaks.
 """
+import sys
+
 import numpy as np
 import pandas as pd
 from matplotlib.dates import MinuteLocator, HourLocator, DayLocator
@@ -141,6 +143,10 @@
         _min = int(np.floor(rng[0]))
         _max = int(np.ceil(rng[1]))
 
+        # Prevent overflow
+        if float(base) ** _max > sys.maxsize:
+            base = float(base)
+
         # 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
@@ -198,6 +204,10 @@
         dtype = float if _min < 0 or _max < 0 else int
         steps = [1]
 
+        # Prevent overflow
+        if float(base) ** _max > sys.maxsize:
+            base = float(base)
+
         def delta(x):
             """
             Calculates the smallest distance in the log scale between the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/formatters.py 
new/mizani-0.7.1/mizani/formatters.py
--- old/mizani-0.6.0/mizani/formatters.py       2019-08-15 14:14:43.000000000 
+0200
+++ new/mizani-0.7.1/mizani/formatters.py       2020-06-04 13:23:00.000000000 
+0200
@@ -369,12 +369,6 @@
         self.base = base
         self.exponent_limits = exponent_limits
 
-        if 'exponent_threshold' in kwargs:
-            warn(
-                 "`exponent_threshold` parameter has been deprecated ",
-                 "Use exponent_limits instead",
-                 DeprecationWarning)
-
     def _tidyup_labels(self, labels):
         """
         Make all labels uniform in format and remove redundant zeros
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/palettes.py 
new/mizani-0.7.1/mizani/palettes.py
--- old/mizani-0.6.0/mizani/palettes.py 2019-08-15 14:14:43.000000000 +0200
+++ new/mizani-0.7.1/mizani/palettes.py 2020-06-04 13:23:00.000000000 +0200
@@ -17,6 +17,7 @@
 import colorsys
 
 import numpy as np
+import pandas as pd
 import matplotlib as mpl
 import matplotlib.colors as mcolors
 from matplotlib.cm import get_cmap
@@ -254,14 +255,12 @@
     grey_cmap = mcolors.LinearSegmentedColormap('grey', cdict)
 
     def continuous_grey_palette(n):
-        colors = []
         # The grey scale points are linearly separated in
         # gamma encoded space
-        for x in np.linspace(start**gamma, end**gamma, n):
-            # Map points onto the [0, 1] palette domain
-            x = (x ** (1./gamma) - start) / (end - start)
-            colors.append(mcolors.rgb2hex(grey_cmap(x)))
-        return colors
+        x = np.linspace(start**gamma, end**gamma, n)
+        # Map points onto the [0, 1] palette domain
+        vals = (x ** (1./gamma) - start) / (end - start)
+        return ratios_to_colors(vals, grey_cmap)
 
     return continuous_grey_palette
 
@@ -368,76 +367,35 @@
     if direction != 1 and direction != -1:
         raise ValueError("direction should be 1 or -1.")
 
-    def full_type_name(text):
-        abbrevs = {
-            'seq': 'Sequential',
-            'qual': 'Qualitative',
-            'div': 'Diverging'
-        }
-        text = abbrevs.get(text, text)
-        return text.title()
-
-    def number_to_palette_name(ctype, n):
-        """
-        Return palette name that corresponds to a given number
-
-        Uses alphabetical ordering
-        """
-        n -= 1
-        palettes = sorted(colorbrewer.COLOR_MAPS[ctype].keys())
-        if n < len(palettes):
-            return palettes[n]
-
-        raise ValueError(
-            "There are only '{}' palettes of type {}. "
-            "You requested palette no. {}".format(len(palettes),
-                                                  ctype, n+1))
-
-    def max_palette_colors(type, palette_name):
-        """
-        Return the number of colors in the brewer palette
-        """
-        if type == 'Sequential':
-            return 9
-        elif type == 'Diverging':
-            return 11
-        else:
-            # Qualitative palettes have different limits
-            qlimit = {'Accent': 8, 'Dark2': 8, 'Paired': 12,
-                      'Pastel1': 9, 'Pastel2': 8, 'Set1': 9,
-                      'Set2': 8, 'Set3': 12}
-            return qlimit[palette_name]
-
-    type = full_type_name(type)
+    type = brewer_helper.full_type_name(type)
     if isinstance(palette, int):
-        palette_name = number_to_palette_name(type, palette)
+        palette_name = brewer_helper.number_to_name(type, palette)
     else:
         palette_name = palette
 
-    nmax = max_palette_colors(type, palette_name)
+    # Get the number of colors in the palette
+    n_max = brewer_helper.num_colors(type, palette_name)
 
     def _brewer_pal(n):
         # Only draw the maximum allowable colors from the palette
         # and fill any remaining spots with None
-        _n = n if n <= nmax else nmax
+        _n = n if n <= n_max else n_max
         try:
             bmap = colorbrewer.get_map(palette_name, type, _n)
-        except ValueError as err:
-            # Some palettes have a minimum no. of colors set at 3
+        except ValueError:
+            # Some palettes have a minimum no. of colors
             # We get around that restriction.
-            if 0 <= _n < 3:
-                bmap = colorbrewer.get_map(palette_name, type, 3)
-            else:
-                raise err
+            n_min = brewer_helper.min_num_colors(type, palette_name)
+            bmap = colorbrewer.get_map(palette_name, type, n_min)
 
         hex_colors = bmap.hex_colors[:n]
-        if n > nmax:
+        if n > n_max:
             msg = ("Warning message:"
-                   "Brewer palette {} has a maximum of {} colors"
-                   "Returning the palette you asked for with"
-                   "that many colors".format(palette_name, nmax))
+                   f"Brewer palette {palette_name} has a maximum "
+                   f"of {n_max} colors Returning the palette you "
+                   "asked for with that many colors")
             warnings.warn(msg)
-            hex_colors = hex_colors + [None] * (n - nmax)
+            hex_colors = hex_colors + [None] * (n - n_max)
         return hex_colors[::direction]
 
     return _brewer_pal
@@ -467,10 +425,14 @@
         values = [values]
 
     color_tuples = colormap(values)
-    try:
-        hex_colors = [mcolors.rgb2hex(t) for t in color_tuples]
-    except IndexError:
-        hex_colors = mcolors.rgb2hex(color_tuples)
+    hex_colors = [mcolors.rgb2hex(t) for t in color_tuples]
+
+    nan_bool_idx = pd.isnull(values) | np.isinf(values)
+    if any(nan_bool_idx):
+        hex_colors = [
+            np.nan if is_nan else color
+            for color, is_nan in zip(hex_colors, nan_bool_idx)
+        ]
     return hex_colors if iterable else hex_colors[0]
 
 
@@ -503,6 +465,8 @@
     >>> palette = gradient_n_pal(['red', 'blue'])
     >>> palette([0, .25, .5, .75, 1])
     ['#ff0000', '#bf0040', '#7f0080', '#3f00c0', '#0000ff']
+    >>> palette([-np.inf, 0, np.nan, 1, np.inf])
+    [nan, '#ff0000', nan, '#0000ff', nan]
     """
     # Note: For better results across devices and media types,
     # it would be better to do the interpolation in
@@ -679,7 +643,7 @@
     def _manual_pal(n):
         if n > max_n:
             msg = ("Palette can return a maximum of {} values. "
-                   "{} were requested from it.")
+                   "{} values requested.")
             warnings.warn(msg.format(max_n, n))
 
         return values[:n]
@@ -822,3 +786,60 @@
     [2, 4, 6]
     """
     return identity
+
+
+def _first_last(it):
+    """
+    First and Last value of iterator as integers
+    """
+    lst = list(it)
+    return int(lst[0]), int(lst[-1])
+
+
+class brewer_helper:
+    """
+    Helper function for useing colorbrewer
+    """
+    _ncolor_range = {
+        t: {
+            palette: _first_last(info.keys())
+            for palette, info in colorbrewer.COLOR_MAPS[t].items()
+           }
+        for t in colorbrewer.COLOR_MAPS
+    }
+
+    @classmethod
+    def num_colors(cls, type, palette):
+        return cls._ncolor_range[type][palette][1]
+
+    @classmethod
+    def min_num_colors(cls, type, palette):
+        return cls._ncolor_range[type][palette][0]
+
+    @staticmethod
+    def full_type_name(text):
+        abbrevs = {
+            'seq': 'Sequential',
+            'qual': 'Qualitative',
+            'div': 'Diverging'
+        }
+        text = abbrevs.get(text, text)
+        return text.title()
+
+    @staticmethod
+    def number_to_name(ctype, n):
+        """
+        Return palette name that corresponds to a given number
+
+        Uses alphabetical ordering
+        """
+        _n = n - 1
+        palettes = sorted(colorbrewer.COLOR_MAPS[ctype].keys())
+        if _n < len(palettes):
+            return palettes[_n]
+
+        npalettes = len(palettes)
+        raise ValueError(
+            f"There are only '{npalettes}' palettes of type {ctype}. "
+            f"You requested palette no. {n}"
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/scale.py 
new/mizani-0.7.1/mizani/scale.py
--- old/mizani-0.6.0/mizani/scale.py    2018-10-11 15:57:40.000000000 +0200
+++ new/mizani-0.7.1/mizani/scale.py    2020-06-05 00:46:31.000000000 +0200
@@ -33,7 +33,7 @@
 
 from .bounds import censor, rescale
 from .utils import CONTINUOUS_KINDS, DISCRETE_KINDS, min_max, match
-from .utils import multitype_sort
+from .utils import get_categories
 
 
 __all__ = ['scale_continuous', 'scale_discrete']
@@ -190,6 +190,8 @@
 
         if old is None:
             old = []
+        else:
+            old = list(old)
 
         # Get the missing values (NaN & Nones) locations and remove them
         nan_bool_idx = pd.isnull(new_data)
@@ -204,29 +206,30 @@
 
         # Train i.e. get the new values
         if pdtypes.is_categorical_dtype(new_data):
-            try:
-                new = list(new_data.cat.categories)  # series
-            except AttributeError:
-                new = list(new_data.categories)      # plain categorical
+            categories = get_categories(new_data)
             if drop:
                 present = set(new_data.drop_duplicates())
-                new = [i for i in new if i in present]
+                new = [i for i in categories if i in present]
+            else:
+                new = list(categories)
         else:
-            try:
-                new = np.unique(new_data)
-                new.sort()
-            except TypeError:
-                # new_data probably has nans and other types
-                new = list(set(new_data))
-                new = multitype_sort(new)
-
-        # Add nan if required
-        if has_na and not na_rm:
-            new = np.hstack([new, np.nan])
+            new = np.unique(new_data)
+            new.sort()
 
         # update old
         old_set = set(old)
-        return list(old) + [i for i in new if (i not in old_set)]
+        if pdtypes.is_categorical_dtype(new_data):
+            # The limits are in the order of the categories
+            all_set = old_set | set(new)
+            ordered_cats = categories.union(old, sort=False)
+            limits = [c for c in ordered_cats if c in all_set]
+        else:
+            limits = old + [i for i in new if (i not in old_set)]
+
+        # Add nan if required
+        if has_na and not na_rm:
+            limits.append(np.nan)
+        return limits
 
     @classmethod
     def map(cls, x, palette, limits, na_value=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/tests/test_breaks.py 
new/mizani-0.7.1/mizani/tests/test_breaks.py
--- old/mizani-0.6.0/mizani/tests/test_breaks.py        2019-07-10 
13:51:46.000000000 +0200
+++ new/mizani-0.7.1/mizani/tests/test_breaks.py        2020-06-04 
13:23:00.000000000 +0200
@@ -65,6 +65,40 @@
     breaks = log_breaks()([1761, 8557])
     npt.assert_array_equal(breaks, [1000, 2000, 3000, 5000, 10000])
 
+    # log_breaks -> _log_sub_breaks -> extended_breaks
+    breaks = log_breaks(13)([1, 10])
+    npt.assert_array_almost_equal(
+        breaks,
+        np.arange(0, 11)
+    )
+
+    # No overflow effects
+    breaks = log_breaks(n=6)([1e25, 1e30])
+    npt.assert_array_almost_equal(
+        breaks,
+        [1e25, 1e26, 1e27, 1e28, 1e29, 1e30]
+    )
+
+    # No overflow effects in _log_sub_breaks
+    breaks = log_breaks()([2e19, 8e19])
+    npt.assert_array_almost_equal(
+        breaks,
+        [1.e+19, 2.e+19, 3.e+19, 5.e+19, 1.e+20]
+    )
+
+    # _log_sub_breaks for base != 10
+    breaks = log_breaks(n=5, base=60)([2e5, 8e5])
+    npt.assert_array_almost_equal(
+        breaks,
+        [129600, 216000, 432000, 648000, 1080000]
+    )
+
+    breaks = log_breaks(n=5, base=2)([20, 80])
+    npt.assert_array_almost_equal(
+        breaks,
+        [16, 32, 64, 128]
+    )
+
 
 def test_minor_breaks():
     # equidistant breaks
@@ -143,6 +177,16 @@
     t = log_trans(base)
     assert len(t.minor_breaks(breaks, limits)) == base - 2
 
+    t = log_trans()
+    major = t.transform([1, 10, 100])
+    limits = t.transform([1, 100])
+    result = trans_minor_breaks(t)(major, limits, n=4)
+    npt.assert_allclose(
+        result,
+        [1.02961942, 1.5260563, 1.85629799, 2.10413415,
+         3.33220451, 3.8286414, 4.15888308, 4.40671925]
+    )
+
 
 def test_date_breaks():
     # cpython
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/tests/test_formatters.py 
new/mizani-0.7.1/mizani/tests/test_formatters.py
--- old/mizani-0.6.0/mizani/tests/test_formatters.py    2019-08-15 
14:14:43.000000000 +0200
+++ new/mizani-0.7.1/mizani/tests/test_formatters.py    2020-06-04 
13:23:00.000000000 +0200
@@ -82,7 +82,6 @@
 
 def test_log_format():
     formatter = log_format()
-
     assert formatter([0.001, 0.1, 100]) == ['0.001', '0.1', '100']
     assert formatter([0.001, 0.1, 10000]) == ['1e-3', '1e-1', '1e4']
     assert formatter([35, 60]) == ['35', '60']
@@ -92,6 +91,8 @@
     assert formatter([1, 35, 60, 1000]) == ['1', '35', '60', '1000']
     assert formatter([1, 35, 60, 10000]) == ['1', '35', '60', '10000']
     assert formatter([3.000000000000001e-05]) == ['3e-5']
+    assert formatter([1, 1e4]) == ['1', '1e4']
+    assert formatter([1, 35, 60, 1e6]) == ['1', '4e1', '6e1', '1e6']
 
     formatter = log_format(base=2)
     assert formatter([1, 10, 11, 1011]) == ['1', '10', '11', '1011']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/tests/test_palettes.py 
new/mizani-0.7.1/mizani/tests/test_palettes.py
--- old/mizani-0.6.0/mizani/tests/test_palettes.py      2019-08-15 
14:14:43.000000000 +0200
+++ new/mizani-0.7.1/mizani/tests/test_palettes.py      2020-06-04 
13:23:00.000000000 +0200
@@ -1,7 +1,7 @@
 import pytest
 import numpy as np
 import numpy.testing as npt
-
+from matplotlib.cm import get_cmap
 
 from mizani.palettes import (hls_palette, husl_palette, rescale_pal,
                              area_pal, abs_area, grey_pal, hue_pal,
@@ -9,6 +9,7 @@
                              cmap_d_pal,
                              desaturate_pal, manual_pal, xkcd_palette,
                              crayon_palette, cubehelix_pal, identity_pal)
+from mizani.palettes import ratios_to_colors
 
 
 def test_hls_palette():
@@ -205,3 +206,9 @@
 
     value = palette(10)
     assert value == 10
+
+
+def test_ratios_to_colors():
+    x = 0.5
+    result = ratios_to_colors(x, get_cmap('viridis'))
+    assert result[0] == '#'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/tests/test_scale.py 
new/mizani-0.7.1/mizani/tests/test_scale.py
--- old/mizani-0.6.0/mizani/tests/test_scale.py 2018-10-08 23:59:27.000000000 
+0200
+++ new/mizani-0.7.1/mizani/tests/test_scale.py 2020-06-05 00:46:31.000000000 
+0200
@@ -39,6 +39,9 @@
     def assert_equal_with_nan(lst1, lst2):
         assert lst1[:-1] == lst2[:-1] and np.isnan(lst2[-1])
 
+    def SCategorical(*args, **kwargs):
+        return pd.Series(pd.Categorical(*args, **kwargs))
+
     x = ['a', 'b', 'c', 'a']
     # apply
     scaled = scale_discrete.apply(x, np.arange)
@@ -87,3 +90,21 @@
 
     limits = scale_discrete.train(x[:2], drop=False)
     assert limits == ['a', 'b', 'c']
+
+    # Disrete Scale training maintains order of categoricals
+    cats = ['x0', 'x1', 'x2', 'x3', 'x4']
+    s1 = SCategorical(['x1', 'x2'], categories=cats)
+    s2 = SCategorical(['x0', 'x2'], categories=cats)
+    limits = scale_discrete.train(s1, drop=True)
+    limits = scale_discrete.train(s2, limits, drop=True)
+    assert limits == ['x0', 'x1', 'x2']
+
+    # Trainning on mixed categories, the last data determines
+    # the location of a value that is in two categoricals
+    # eg. a & e are ordered right!
+    x1 = pd.Categorical(['a', 'b', 'c', 'e'])
+    x2 = pd.Categorical(['d', 'f', 'e', 'a'])
+    limits = scale_discrete.train(x1)
+    limits = scale_discrete.train(x2, old=limits)
+    # assert limits == list('abcedf')
+    assert limits == list('adefbc')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/tests/test_transforms.py 
new/mizani-0.7.1/mizani/tests/test_transforms.py
--- old/mizani-0.6.0/mizani/tests/test_transforms.py    2019-08-15 
14:14:43.000000000 +0200
+++ new/mizani-0.7.1/mizani/tests/test_transforms.py    2020-06-04 
13:23:00.000000000 +0200
@@ -96,12 +96,25 @@
 
 
 def test_boxcox_trans():
-    _test_trans(boxcox_trans(0), arr)
     _test_trans(boxcox_trans(0.5), arr*10)
+    _test_trans(boxcox_trans(1), arr)
     with pytest.raises(ValueError):
         x = np.arange(-4, 4)
         _test_trans(boxcox_trans(0.5), x)
 
+    # Special case, small p and p = 0
+    with pytest.warns(RuntimeWarning):
+        _test_trans(boxcox_trans(1e-8), arr)
+        _test_trans(boxcox_trans(0), arr)
+
+    x = [0, 1, 2, 3]
+    t = boxcox_trans(0)
+    with pytest.warns(RuntimeWarning):
+        xt = t.transform(x)
+    xti = t.inverse(xt)
+    assert np.isneginf(xt[0])
+    npt.assert_array_almost_equal(x, xti)
+
 
 def test_modulus_trans():
     _test_trans(modulus_trans(0), arr)
@@ -163,6 +176,11 @@
     pos = [10 ** int(x) for x in p]
     arr = np.hstack([-np.array(pos[::-1]), pos])
     _test_trans(pseudo_log_trans, arr)
+    _test_trans(pseudo_log_trans(base=16), arr)
+    _test_trans(
+        pseudo_log_trans(base=10, minor_breaks=minor_breaks(n=5)),
+        arr
+    )
 
 
 def test_probability_trans():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/tests/test_utils.py 
new/mizani-0.7.1/mizani/tests/test_utils.py
--- old/mizani-0.6.0/mizani/tests/test_utils.py 2019-03-26 16:25:25.000000000 
+0100
+++ new/mizani-0.7.1/mizani/tests/test_utils.py 2020-06-03 21:48:57.000000000 
+0200
@@ -5,7 +5,7 @@
 
 from mizani.utils import (round_any, min_max, match, precision,
                           first_element, multitype_sort,
-                          same_log10_order_of_magnitude)
+                          same_log10_order_of_magnitude, get_categories)
 
 
 def test_round_any():
@@ -139,3 +139,20 @@
     assert same_log10_order_of_magnitude((1, 9.9), delta=0)
     assert same_log10_order_of_magnitude((35, 91), delta=0)
     assert same_log10_order_of_magnitude((232.3, 950), delta=0)
+
+
+def test_get_categories():
+    lst = list('abcd')
+    s = pd.Series(lst)
+    c = pd.Categorical(lst)
+    sc = pd.Series(c)
+
+    categories = pd.Index(lst)
+    assert categories.equals(get_categories(c))
+    assert categories.equals(get_categories(sc))
+
+    with pytest.raises(TypeError):
+        assert categories.equals(get_categories(lst))
+
+    with pytest.raises(TypeError):
+        assert categories.equals(get_categories(s))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/transforms.py 
new/mizani-0.7.1/mizani/transforms.py
--- old/mizani-0.6.0/mizani/transforms.py       2019-08-15 14:14:43.000000000 
+0200
+++ new/mizani-0.7.1/mizani/transforms.py       2020-06-04 13:23:00.000000000 
+0200
@@ -435,9 +435,6 @@
     :func:`~mizani.transforms.modulus_trans`
 
     """
-    if np.abs(p) < 1e-7:
-        return log_trans()
-
     def transform(x):
         x = np.asarray(x)
         if np.any((x + offset) < 0):
@@ -608,16 +605,7 @@
         """
         Transform from date to a numerical format
         """
-        try:
-            x = date2num(x)
-        except AttributeError:
-            # numpy datetime64
-            # This is not ideal because the operations do not
-            # preserve the np.datetime64 type. May be need
-            # a datetime64_trans
-            x = [pd.Timestamp(item) for item in x]
-            x = date2num(x)
-        return x
+        return date2num(x)
 
     @staticmethod
     def inverse(x):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani/utils.py 
new/mizani-0.7.1/mizani/utils.py
--- old/mizani-0.6.0/mizani/utils.py    2019-08-07 23:49:09.000000000 +0200
+++ new/mizani-0.7.1/mizani/utils.py    2020-06-04 13:23:00.000000000 +0200
@@ -6,8 +6,8 @@
 
 __all__ = ['round_any', 'min_max', 'match',
            'precision', 'first_element', 'multitype_sort',
-           'is_close_to_int', 'same_log10_order_of_magnitude',
-           'identity'
+           'same_log10_order_of_magnitude',
+           'identity', 'get_categories'
            ]
 
 DISCRETE_KINDS = 'ObUS'
@@ -224,36 +224,6 @@
     return list(chain(*(types[t] for t in types)))
 
 
-def nearest_int(x):
-    """
-    Return nearest long integer to x
-    """
-    if x == 0:
-        return np.int64(0)
-    elif x > 0:
-        return np.int64(x + 0.5)
-    else:
-        return np.int64(x - 0.5)
-
-
-def is_close_to_int(x):
-    """
-    Check if value is close to an integer
-
-    Parameters
-    ----------
-    x : float
-        Numeric value to check
-
-    Returns
-    -------
-    out : bool
-    """
-    if not np.isfinite(x):
-        return False
-    return abs(x - nearest_int(x)) < 1e-10
-
-
 def same_log10_order_of_magnitude(x, delta=0.1):
     """
     Return true if range is approximately in same order of magnitude
@@ -282,3 +252,26 @@
     Return whatever is passed in
     """
     return args if len(args) > 1 else args[0]
+
+
+def get_categories(x):
+    """
+    Return the categories of x
+
+    Parameters
+    ----------
+    x : category_like
+        Input Values
+
+    Returns
+    -------
+    out : Index
+        Categories of x
+    """
+    try:
+        return x.cat.categories  # series
+    except AttributeError:
+        try:
+            return x.categories   # plain categorical
+        except AttributeError:
+            raise TypeError("x is the wrong type, it has no categories")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani.egg-info/PKG-INFO 
new/mizani-0.7.1/mizani.egg-info/PKG-INFO
--- old/mizani-0.6.0/mizani.egg-info/PKG-INFO   2019-08-15 14:38:39.000000000 
+0200
+++ new/mizani-0.7.1/mizani.egg-info/PKG-INFO   2020-06-05 00:46:53.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: mizani
-Version: 0.6.0
+Version: 0.7.1
 Summary: Scales for Python
 Home-page: https://github.com/has2k1/mizani
 Maintainer: Hassan Kibirige
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/mizani.egg-info/requires.txt 
new/mizani-0.7.1/mizani.egg-info/requires.txt
--- old/mizani-0.6.0/mizani.egg-info/requires.txt       2019-08-15 
14:38:39.000000000 +0200
+++ new/mizani-0.7.1/mizani.egg-info/requires.txt       2020-06-05 
00:46:53.000000000 +0200
@@ -1,4 +1,4 @@
 numpy
-pandas>=0.25.0
+pandas>=1.0.0
 matplotlib>=3.1.1
 palettable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/setup.cfg new/mizani-0.7.1/setup.cfg
--- old/mizani-0.6.0/setup.cfg  2019-08-15 14:38:39.000000000 +0200
+++ new/mizani-0.7.1/setup.cfg  2020-06-05 00:46:54.000000000 +0200
@@ -1,6 +1,3 @@
-[wheel]
-universal = 1
-
 [versioneer]
 vcs = git
 style = pep440
@@ -10,7 +7,7 @@
 parentdir_prefix = mizani-
 
 [flake8]
-ignore = E121,E123,E126,E226,E24,E704,W503,W504,E741
+ignore = E121,E123,E126,E226,E24,E704,W503,W504,E741,E743
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mizani-0.6.0/setup.py new/mizani-0.7.1/setup.py
--- old/mizani-0.6.0/setup.py   2019-08-15 14:15:37.000000000 +0200
+++ new/mizani-0.7.1/setup.py   2020-06-03 21:48:57.000000000 +0200
@@ -15,6 +15,12 @@
 __description__ = "Scales for Python"
 __license__ = 'BSD (3-clause)'
 __url__ = 'https://github.com/has2k1/mizani'
+__classifiers__ = [
+    'Intended Audience :: Science/Research',
+    'License :: OSI Approved :: BSD License',
+    'Programming Language :: Python :: 3',
+    'Topic :: Scientific/Engineering :: Visualization',
+]
 
 
 def check_dependencies():
@@ -31,7 +37,7 @@
     Plus any version tests and warnings
     """
     install_requires = ['numpy',
-                        'pandas >= 0.25.0',
+                        'pandas >= 1.0.0',
                         'matplotlib >= 3.1.1',
                         'palettable']
     return install_requires
@@ -72,10 +78,5 @@
           install_requires=get_required_packages(),
           packages=find_packages(),
           package_data=get_package_data(),
-          classifiers=[
-              'Intended Audience :: Science/Research',
-              'License :: OSI Approved :: BSD License',
-              'Programming Language :: Python :: 3',
-              'Topic :: Scientific/Engineering :: Visualization',
-          ],
+          classifiers=__classifiers__
           )


Reply via email to