예제 #1
0
    def infer_scale(self, arg: Any, data: Series) -> Scale:
        """Given data and a scaling argument, initialize appropriate scale class."""

        # TODO infer continuous based on log/sqrt etc?

        if isinstance(arg, (list, dict)):
            return Nominal(arg)
        elif variable_type(data) == "categorical":
            return Nominal(arg)
        elif variable_type(data) == "datetime":
            return Temporal(arg)
        # TODO other variable types
        else:
            return Continuous(arg)
예제 #2
0
    def test_object_defaults(self, x):
        class MockProperty(ObjectProperty):
            def _default_values(self, n):
                return list("xyz"[:n])

        s = Nominal()._setup(x, MockProperty())
        assert s(x) == ["x", "y", "z", "y"]
예제 #3
0
    def test_interval_with_transform(self, x):
        class MockProperty(IntervalProperty):
            _forward = np.square
            _inverse = np.sqrt

        s = Nominal((2, 4))._setup(x, MockProperty())
        assert_array_equal(s(x), [4, np.sqrt(10), 2, np.sqrt(10)])
예제 #4
0
    def test_coordinate_numeric_data(self, y):

        ax = mpl.figure.Figure().subplots()
        s = Nominal()._setup(y, Coordinate(), ax.yaxis)
        assert_array_equal(s(y), np.array([1, 0, 2, 0], float))
        f = ax.yaxis.get_major_formatter()
        assert f.format_ticks([0, 1, 2]) == ["-1.5", "1.0", "3.0"]
예제 #5
0
    def test_coordinate_axis(self, x):

        ax = mpl.figure.Figure().subplots()
        s = Nominal()._setup(x, Coordinate(), ax.xaxis)
        assert_array_equal(s(x), np.array([0, 1, 2, 1], float))
        f = ax.xaxis.get_major_formatter()
        assert f.format_ticks([0, 1, 2]) == ["a", "c", "b"]
예제 #6
0
    def test_color_numeric_int_float_mix(self):

        z = pd.Series([1, 2], name="z")
        s = Nominal(order=[1.0, 2])._setup(z, Color())
        c1, c2 = color_palette(n_colors=2)
        null = (np.nan, np.nan, np.nan)
        assert_array_equal(s(z), [c1, null, c2])
예제 #7
0
    def test_interval_defaults(self, x):

        class MockProperty(IntervalProperty):
            _default_range = (1, 2)

        s = Nominal().setup(x, MockProperty())
        assert_array_equal(s(x), [2, 1.5, 1, 1.5])
예제 #8
0
    def test_coordinate_numeric_data_with_order(self, y):

        order = [1, 4, -1.5]
        ax = mpl.figure.Figure().subplots()
        s = Nominal(order=order)._setup(y, Coordinate(), ax.yaxis)
        assert_array_equal(s(y), np.array([0, 2, np.nan, 2], float))
        f = ax.yaxis.get_major_formatter()
        assert f.format_ticks([0, 1, 2]) == ["1.0", "4.0", "-1.5"]
예제 #9
0
    def test_coordinate_axis_with_subset_order(self, x):

        order = ["c", "a"]
        ax = mpl.figure.Figure().subplots()
        s = Nominal(order=order)._setup(x, Coordinate(), ax.xaxis)
        assert_array_equal(s(x), np.array([1, 0, np.nan, 0], float))
        f = ax.xaxis.get_major_formatter()
        assert f.format_ticks([0, 1, 2]) == [*order, ""]
예제 #10
0
    def test_coordinate_axis_with_category_dtype(self, x):

        order = ["b", "a", "d", "c"]
        x = x.astype(pd.CategoricalDtype(order))
        ax = mpl.figure.Figure().subplots()
        s = Nominal()._setup(x, Coordinate(), ax.xaxis)
        assert_array_equal(s(x), np.array([1, 3, 0, 3], float))
        f = ax.xaxis.get_major_formatter()
        assert f.format_ticks([0, 1, 2, 3]) == order
예제 #11
0
    def infer_scale(self, arg: Any, data: Series) -> Scale:
        # TODO when inferring Continuous without data, verify type

        # TODO need to rethink the variable type system
        # (e.g. boolean, ordered categories as Ordinal, etc)..
        var_type = variable_type(data, boolean_type="categorical")

        if isinstance(arg, (dict, list)):
            return Nominal(arg)

        if isinstance(arg, tuple):
            if var_type == "categorical":
                # TODO It seems reasonable to allow a gradient mapping for nominal
                # scale but it also feels "technically" wrong. Should this infer
                # Ordinal with categorical data and, if so, verify orderedness?
                return Nominal(arg)
            return Continuous(arg)

        if callable(arg):
            return Continuous(arg)

        # TODO Do we accept str like "log", "pow", etc. for semantics?

        # TODO what about
        # - Temporal? (i.e. datetime)
        # - Boolean?

        if not isinstance(arg, str):
            msg = " ".join([
                f"A single scale argument for {self.variable} variables must be",
                f"a string, dict, tuple, list, or callable, not {type(arg)}."
            ])
            raise TypeError(msg)

        if arg in QUAL_PALETTES:
            return Nominal(arg)
        elif var_type == "numeric":
            return Continuous(arg)
        # TODO implement scales for date variables and any others.
        else:
            return Nominal(arg)
예제 #12
0
 def default_scale(self, data: Series) -> Scale:
     """Given data, initialize appropriate scale class."""
     # TODO allow variable_type to be "boolean" if that's a scale?
     # TODO how will this handle data with units that can be treated as numeric
     # if passed through a registered matplotlib converter?
     var_type = variable_type(data, boolean_type="numeric")
     if var_type == "numeric":
         return Continuous()
     elif var_type == "datetime":
         return Temporal()
     # TODO others
     # time-based (TimeStamp, TimeDelta, Period)
     # boolean scale?
     else:
         return Nominal()
예제 #13
0
    def test_interval_tuple(self, x):

        s = Nominal((1, 2))._setup(x, IntervalProperty())
        assert_array_equal(s(x), [2, 1.5, 1, 1.5])
예제 #14
0
    def test_fill_nunique_warning(self):

        x = pd.Series(["a", "b", "c", "a", "b"], name="x")
        with pytest.warns(UserWarning, match="The variable assigned to fill"):
            s = Nominal()._setup(x, Fill())
        assert_array_equal(s(x), [True, False, True, True, False])
예제 #15
0
    def test_fill_dict(self):

        x = pd.Series(["a", "a", "b", "a"], name="x")
        vs = {"a": False, "b": True}
        s = Nominal(vs)._setup(x, Fill())
        assert_array_equal(s(x), [False, False, True, False])
예제 #16
0
    def test_fill(self):

        x = pd.Series(["a", "a", "b", "a"], name="x")
        s = Nominal()._setup(x, Fill())
        assert_array_equal(s(x), [True, True, False, True])
예제 #17
0
    def test_alpha_default(self, x):

        s = Nominal()._setup(x, Alpha())
        assert_array_equal(s(x), [.95, .625, .3, .625])
예제 #18
0
    def test_color_numeric_data(self, y):

        s = Nominal()._setup(y, Color())
        cs = color_palette()
        assert_array_equal(s(y), [cs[1], cs[0], cs[2], cs[0]])
예제 #19
0
    def test_interval_dict(self, x):

        vs = {"a": 3, "b": 4, "c": 6}
        s = Nominal(vs)._setup(x, IntervalProperty())
        assert_array_equal(s(x), [3, 6, 4, 6])
예제 #20
0
    def test_object_order(self, x):

        vs = ["x", "y", "z"]
        s = Nominal(vs, order=["c", "a", "b"])._setup(x, ObjectProperty())
        assert s(x) == ["y", "x", "z", "x"]
예제 #21
0
    def test_object_dict(self, x):

        vs = {"a": "x", "b": "y", "c": "z"}
        s = Nominal(vs)._setup(x, ObjectProperty())
        assert s(x) == ["x", "z", "y", "z"]
예제 #22
0
    def test_color_dict_palette(self, x):

        cs = color_palette("crest", 3)
        pal = dict(zip("bac", cs))
        s = Nominal(pal)._setup(x, Color())
        assert_array_equal(s(x), [cs[1], cs[2], cs[0], cs[2]])
예제 #23
0
    def test_color_unknown_palette(self, x):

        pal = "not_a_palette"
        err = f"{pal} is not a valid palette name"
        with pytest.raises(ValueError, match=err):
            Nominal(pal)._setup(x, Color())
예제 #24
0
    def test_color_alpha_in_palette(self, x):

        cs = [(.2, .2, .3, .5), (.1, .2, .3, 1), (.5, .6, .2, 0)]
        s = Nominal(cs)._setup(x, Color())
        assert_array_equal(s(x), [cs[0], cs[1], cs[2], cs[1]])
예제 #25
0
    def test_interval_tuple_numeric(self, y):

        s = Nominal((1, 2))._setup(y, IntervalProperty())
        assert_array_equal(s(y), [1.5, 2, 1, 2])
예제 #26
0
    def test_object_order_subset(self, x):

        vs = ["x", "y"]
        s = Nominal(vs, order=["a", "c"])._setup(x, ObjectProperty())
        assert s(x) == ["x", "y", None, "y"]
예제 #27
0
    def test_interval_list(self, x):

        vs = [2, 5, 4]
        s = Nominal(vs)._setup(x, IntervalProperty())
        assert_array_equal(s(x), [2, 5, 4, 5])
예제 #28
0
    def test_objects_that_are_weird(self, x):

        vs = [("x", 1), (None, None, 0), {}]
        s = Nominal(vs)._setup(x, ObjectProperty())
        assert s(x) == [vs[0], vs[1], vs[2], vs[1]]
예제 #29
0
    def test_object_list(self, x):

        vs = ["x", "y", "z"]
        s = Nominal(vs)._setup(x, ObjectProperty())
        assert s(x) == ["x", "y", "z", "y"]
예제 #30
0
    def test_color_numeric_with_order_subset(self, y):

        s = Nominal(order=[-1.5, 1])._setup(y, Color())
        c1, c2 = color_palette(n_colors=2)
        null = (np.nan, np.nan, np.nan)
        assert_array_equal(s(y), [c2, c1, null, c1])