Beispiel #1
0
    def test_hash_omit_style(self):
        class N(Node):
            my_attr = tl.Int().tag(attr=True)

        n1 = N(my_attr=1, style=Style(name="a"))
        n2 = N(my_attr=1, style=Style(name="b"))

        # json has style in it
        assert n1.json != n2.json

        # but hash does not
        assert n1.hash == n2.hash
Beispiel #2
0
    def test_eq_ignore_style(self):
        class N(Node):
            my_attr = tl.Int().tag(attr=True)

        n1 = N(my_attr=1, style=Style(name="a"))
        n2 = N(my_attr=1, style=Style(name="b"))

        # json has style in it
        assert n1.json != n2.json

        # but == and != don't care
        assert n1 == n2
        assert not n1 != n2
Beispiel #3
0
    def test_enumeration(self):
        # matplotlib enumeration tuples
        style = Style(
            enumeration_colors={
                1: "r",
                3: "o"
            },
            enumeration_legend={
                1: "apples",
                3: "oranges"
            },
            default_enumeration_color="k",
        )
        assert style.full_enumeration_colors == ("r", "k", "o")
        assert style.full_enumeration_legend == ("apples", "unknown",
                                                 "oranges")

        # negative key
        style = Style(
            enumeration_colors={
                -1: "r",
                1: "o"
            },
            enumeration_legend={
                -1: "apples",
                1: "oranges"
            },
            default_enumeration_color="k",
        )
        assert style.full_enumeration_colors == ("r", "k", "o")
        assert style.full_enumeration_legend == ("apples", "unknown",
                                                 "oranges")

        # invalid
        with pytest.raises(
                ValueError,
                match=
                "Style enumeration_legend keys must match enumeration_colors keys"
        ):
            style = Style(enumeration_colors={
                1: "r",
                3: "o"
            },
                          enumeration_legend={1: "apples"})

        with pytest.raises(
                TypeError,
                match="Style enumeration_legend requires enumeration_colors"):
            style = Style(enumeration_legend={-1: "apples", 3: "oranges"})
Beispiel #4
0
    def test_eq(self):
        style1 = Style(name="test")
        style2 = Style(name="test")
        style3 = Style(name="other")

        assert style1 is not style2
        assert style1 is not style3
        assert style2 is not style3

        assert style1 == style1
        assert style2 == style2
        assert style3 == style3

        assert style1 == style2
        assert style1 != style3
Beispiel #5
0
    def test_cmap(self):
        style = Style()
        assert style.cmap.name == "viridis"

        style = Style(colormap="cividis")
        assert style.cmap.name == "cividis"

        style = Style(enumeration_colors=("c", "k"))
        assert style.cmap.name == "from_list"
        assert style.cmap.colors == ("c", "k")

        with pytest.raises(
                TypeError,
                match="Style can have a colormap or enumeration_colors"):
            style = Style(colormap="cividis", enumeration_colors=("c", "k"))
Beispiel #6
0
 def test_serialization_deserialization(self):
     n_lats = 3
     n_lons = 4
     n_alts = 2
     a = UnitsDataArray(
         np.arange(n_lats * n_lons * n_alts).reshape(
             (n_lats, n_lons, n_alts)),
         dims=["lat", "lon", "alt"],
         attrs={
             "units": ureg.meter,
             "layer_style": Style()
         },
     )
     f = a.to_netcdf()
     b = UnitsDataArray(xr.open_dataarray(f))
     assert a.attrs["units"] == b.attrs["units"]
     assert a.attrs["layer_style"].json == b.attrs["layer_style"].json
Beispiel #7
0
    def test_serialization(self):
        # default
        style = Style()
        d = style.definition
        assert isinstance(d, OrderedDict)
        assert len(d.keys()) == 0

        s = Style.from_json(style.json)
        assert isinstance(s, Style)

        # with traits
        style = Style(name="test",
                      units="meters",
                      colormap="cividis",
                      clim=(-1, 1))
        d = style.definition
        assert isinstance(d, OrderedDict)
        assert set(d.keys()) == {"name", "units", "colormap", "clim"}
        assert d["name"] == "test"
        assert d["units"] == "meters"
        assert d["colormap"] == "cividis"
        assert d["clim"] == [-1, 1]

        s = Style.from_json(style.json)
        assert s.name == style.name
        assert s.units == style.units
        assert s.colormap == style.colormap
        assert s.clim == style.clim

        # enumeration traits
        style = Style(enumeration_legend=({
            0: "apples",
            1: "oranges"
        }),
                      enumeration_colors=({
                          0: "r",
                          1: "o"
                      }))
        d = style.definition
        assert isinstance(d, OrderedDict)
        assert set(d.keys()) == {"enumeration_legend", "enumeration_colors"}
        assert d["enumeration_legend"] == {0: "apples", 1: "oranges"}
        assert d["enumeration_colors"] == {0: "r", 1: "o"}

        s = Style.from_json(style.json)
        assert s.enumeration_legend == style.enumeration_legend
        assert s.enumeration_colors == style.enumeration_colors
        assert s.cmap.colors == style.cmap.colors
Beispiel #8
0
    def test_style(self):
        node = podpac.data.Array(
            source=[10, 20, 30],
            coordinates=podpac.Coordinates([[0, 1, 2]], dims=["lat"]),
            style=Style(name="test", units="m"),
        )

        d = node.definition
        assert "style" in d[node.base_ref]

        node2 = Node.from_definition(d)
        assert node2 is not node
        assert isinstance(node2, podpac.data.Array)
        assert node2.style is not node.style
        assert node2.style == node.style
        assert node2.style.name == "test"
        assert node2.style.units == "m"

        # default style
        node = podpac.data.Array(source=[10, 20, 30],
                                 coordinates=podpac.Coordinates([[0, 1, 2]],
                                                                dims=["lat"]))
        d = node.definition
        assert "style" not in d[node.base_ref]
Beispiel #9
0
 def _default_style(self):
     return Style(clim=[-1.0, 1.0], colormap="jet")
Beispiel #10
0
 def test_init(self):
     s = Style()
Beispiel #11
0
    def from_definition(cls, definition):
        """
        Create podpac Node from a dictionary definition.

        Arguments
        ---------
        d : dict
            node definition

        Returns
        -------
        :class:`Node`
            podpac Node

        See Also
        --------
        definition : node definition as a dictionary
        from_json : create podpac node from a JSON definition
        load : create a node from file
        """

        if "podpac_version" in definition and definition[
                "podpac_version"] != podpac.__version__:
            warnings.warn("node definition version mismatch "
                          "(this node was created with podpac version '%s', "
                          "but your current podpac version is '%s')" %
                          (definition["podpac_version"], podpac.__version__))

        if len(definition) == 0:
            raise ValueError("Invalid definition: definition cannot be empty.")

        # parse node definitions in order
        nodes = OrderedDict()
        for name, d in definition.items():
            if name == "podpac_version":
                continue

            if "node" not in d:
                raise ValueError(
                    "Invalid definition for node '%s': 'node' property required"
                    % name)

            # get node class
            module_root = d.get("plugin", "podpac")
            node_string = "%s.%s" % (module_root, d["node"])
            module_name, node_name = node_string.rsplit(".", 1)
            try:
                module = importlib.import_module(module_name)
            except ImportError:
                raise ValueError(
                    "Invalid definition for node '%s': no module found '%s'" %
                    (name, module_name))
            try:
                node_class = getattr(module, node_name)
            except AttributeError:
                raise ValueError(
                    "Invalid definition for node '%s': class '%s' not found in module '%s'"
                    % (name, node_name, module_name))

            # parse and configure kwargs
            kwargs = {}
            for k, v in d.get("attrs", {}).items():
                kwargs[k] = v

            for k, v in d.get("inputs", {}).items():
                kwargs[k] = _lookup_input(nodes, name, v)

            for k, v in d.get("lookup_attrs", {}).items():
                kwargs[k] = _lookup_attr(nodes, name, v)

            if "style" in d:
                kwargs["style"] = Style.from_definition(d["style"])

            for k in d:
                if k not in [
                        "node", "inputs", "attrs", "lookup_attrs", "plugin",
                        "style"
                ]:
                    raise ValueError(
                        "Invalid definition for node '%s': unexpected property '%s'"
                        % (name, k))

            nodes[name] = node_class(**kwargs)

        return list(nodes.values())[-1]
Beispiel #12
0
    def test_init_from_node(self):
        from podpac.core.node import Node

        node = Node()
        s = Style(node)
Beispiel #13
0
 def test_base_definition_style(self):
     node = Node(style=Style(name="test"))
     d = node._base_definition
     assert "style" in node._base_definition
Beispiel #14
0
 def test_basic_creation(self):
     s = Style()
Beispiel #15
0
def to_image(data, format="png", vmin=None, vmax=None, return_base64=False):
    """Return a base64-encoded image of data

    Parameters
    ----------
    data : array-like
        data to output, usually a UnitsDataArray
    format : str, optional
        Default is 'png'. Type of image.
    vmin : number, optional
        Minimum value of colormap
    vmax : vmax, optional
        Maximum value of colormap
    return_base64: bool, optional
        Default is False. Normally this returns an io.BytesIO, but if True, will return a base64 encoded string.


    Returns
    -------
    BytesIO/str
        Binary or Base64 encoded image.
    """

    import matplotlib
    import matplotlib.cm
    from matplotlib.image import imsave

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        matplotlib.use("agg")

    if format != "png":
        raise ValueError("Invalid image format '%s', must be 'png'" % format)

    style = None
    if isinstance(data, xr.DataArray):
        style = data.attrs.get("layer_style", None)
        if isinstance(style, string_types):
            style = Style.from_json(style)
        dims = data.squeeze().dims
        y = data.coords[dims[0]]
        x = data.coords[dims[1]]
        data = data.data
        if y[1] > y[0]:
            data = data[::-1, :]
        if x[1] < x[0]:
            data = data[:, ::1]

    data = data.squeeze()

    if not np.any(np.isfinite(data)):
        vmin = 0
        vmax = 1
    else:
        if vmin is None or np.isnan(vmin):
            if style is not None and style.clim[0] != None:
                vmin = style.clim[0]
            else:
                vmin = np.nanmin(data)
        if vmax is None or np.isnan(vmax):
            if style is not None and style.clim[1] != None:
                vmax = style.clim[1]
            else:
                vmax = np.nanmax(data)
    if vmax == vmin:
        vmax += 1e-15

    # get the colormap
    if style is None:
        cmap = matplotlib.cm.viridis
    else:
        cmap = style.cmap

    c = (data - vmin) / (vmax - vmin)
    i = cmap(c, bytes=True)
    i[np.isnan(c), 3] = 0
    im_data = BytesIO()
    imsave(im_data, i, format=format)
    im_data.seek(0)
    if return_base64:
        return base64.b64encode(im_data.getvalue())
    else:
        return im_data
Beispiel #16
0
 def test_get_default_cmap(self):
     style = Style()
     style.cmap
Beispiel #17
0
 def test_create_with_node(self):
     node = Node()
     s = Style(node)
Beispiel #18
0
 def _style_default(self):
     return Style()
Beispiel #19
0
    def from_definition(cls, definition):
        """
        Create podpac Node from a dictionary definition.

        Arguments
        ---------
        d : dict
            node definition

        Returns
        -------
        :class:`Node`
            podpac Node

        See Also
        --------
        definition : node definition as a dictionary
        from_json : create podpac node from a JSON definition
        load : create a node from file
        """

        if "podpac_version" in definition and definition["podpac_version"] != podpac.__version__:
            warnings.warn(
                "node definition version mismatch "
                "(this node was created with podpac version '%s', "
                "but your current podpac version is '%s')" % (definition["podpac_version"], podpac.__version__)
            )

        if len(definition) == 0:
            raise ValueError("Invalid definition: definition cannot be empty.")

        # parse node definitions in order
        nodes = OrderedDict()
        for name, d in definition.items():
            if name == "podpac_version":
                continue

            if "node" not in d:
                raise ValueError("Invalid definition for node '%s': 'node' property required" % name)

            # get node class
            module_root = d.get("plugin", "podpac")
            node_string = "%s.%s" % (module_root, d["node"])
            module_name, node_name = node_string.rsplit(".", 1)
            try:
                module = importlib.import_module(module_name)
            except ImportError:
                raise ValueError("Invalid definition for node '%s': no module found '%s'" % (name, module_name))
            try:
                node_class = getattr(module, node_name)
            except AttributeError:
                raise ValueError(
                    "Invalid definition for node '%s': class '%s' not found in module '%s'"
                    % (name, node_name, module_name)
                )

            # parse and configure kwargs
            kwargs = {}
            for k, v in d.get("attrs", {}).items():
                kwargs[k] = v

            for k, v in d.get("inputs", {}).items():
                kwargs[k] = _lookup_input(nodes, name, v)

            for k, v in d.get("lookup_attrs", {}).items():
                kwargs[k] = _lookup_attr(nodes, name, v)

            if "style" in d:
                style_class = getattr(node_class, 'style', Style)
                if isinstance(style_class, tl.TraitType):
                    # Now we actually have to look through the class to see
                    # if there is a custom initializer for style
                    for attr in dir(node_class):
                        atr = getattr(node_class, attr)
                        if not isinstance(atr, tl.traitlets.DefaultHandler) or atr.trait_name != 'style':
                            continue
                        try:
                            style_class = atr(node_class)
                        except Exception as e:
                            # print ("couldn't make style from class", e)
                            try:
                                style_class = atr(node_class())
                            except:
                                # print ("couldn't make style from class instance", e)
                                style_class = style_class.klass
                try:
                    kwargs["style"] = style_class.from_definition(d["style"])
                except Exception as e:
                    kwargs["style"] = Style.from_definition(d["style"])
                    # print ("couldn't make style from inferred style class", e)



            for k in d:
                if k not in ["node", "inputs", "attrs", "lookup_attrs", "plugin", "style"]:
                    raise ValueError("Invalid definition for node '%s': unexpected property '%s'" % (name, k))

            nodes[name] = node_class(**kwargs)

        return list(nodes.values())[-1]
Beispiel #20
0
 def _default_style(self):
     return Style()