Exemple #1
0
    def __init__(self, data_or_path, mode=None, caption=None, grouping=None):
        """
        Accepts numpy array of image data, or a PIL image. The class attempts to infer
        the data format and converts it.

        If grouping is set to a number the interface combines N images.
        """

        self._grouping = grouping
        self._caption = caption
        self._width = None
        self._height = None
        self._image = None

        if isinstance(data_or_path, six.string_types):
            super(Image, self).__init__(data_or_path, is_tmp=False)
        else:
            data = data_or_path

            PILImage = util.get_module(
                "PIL.Image",
                required=
                'wandb.Image needs the PIL package. To get it, run "pip install pillow".'
            )
            if util.is_matplotlib_typename(util.get_full_typename(data)):
                buf = six.BytesIO()
                util.ensure_matplotlib_figure(data).savefig(buf)
                self._image = PILImage.open(buf)
            elif isinstance(data, PILImage.Image):
                self._image = data
            elif util.is_pytorch_tensor_typename(util.get_full_typename(data)):
                vis_util = util.get_module(
                    "torchvision.utils",
                    "torchvision is required to render images")
                if hasattr(data, "requires_grad") and data.requires_grad:
                    data = data.detach()
                data = vis_util.make_grid(data, normalize=True)
                self._image = PILImage.fromarray(
                    data.mul(255).clamp(0,
                                        255).byte().permute(1, 2,
                                                            0).cpu().numpy())
            else:
                if hasattr(data, "numpy"):  # TF data eager tensors
                    data = data.numpy()
                if data.ndim > 2:
                    data = data.squeeze(
                    )  # get rid of trivial dimensions as a convenience
                self._image = PILImage.fromarray(self.to_uint8(data),
                                                 mode=mode
                                                 or self.guess_mode(data))

            self._width, self._height = self._image.size

            tmp_path = os.path.join(MEDIA_TMP.name,
                                    util.generate_id() + '.png')
            self._image.save(tmp_path, transparency=None)
            super(Image, self).__init__(tmp_path, is_tmp=True)
Exemple #2
0
def plot_to_json(obj):
    """Converts a matplotlib or plotly object to json so that we can pass
        it the the wandb server and display it nicely there"""

    if util.is_matplotlib_typename(util.get_full_typename(obj)):
        tools = util.get_module(
            "plotly.tools", required="plotly is required to log interactive plots, install with: pip install plotly or convert the plot to an image with `wandb.Image(plt)`")
        obj = tools.mpl_to_plotly(obj)

    if util.is_plotly_typename(util.get_full_typename(obj)):
        return {"_type": "plotly", "plot": numpy_arrays_to_lists(obj.to_plotly_json())}
    else:
        return obj
Exemple #3
0
def plot_to_json(obj):
    if util.is_matplotlib_typename(util.get_full_typename(obj)):
        tools = util.get_module(
            "plotly.tools",
            required=
            "plotly is required to log interactive plots, install with: pip install plotly or convert the plot to an image with `wandb.Image(plt)`"
        )
        obj = tools.mpl_to_plotly(obj)

    if util.is_plotly_typename(util.get_full_typename(obj)):
        return {"_type": "plotly", "plot": obj.to_plotly_json()}
    else:
        return obj
Exemple #4
0
    def __init__(self, data, mode=None, caption=None, grouping=None):
        """
        Accepts numpy array of image data, or a PIL image. The class attempts to infer
        the data format and converts it.

        If grouping is set to a number the interface combines N images.
        """

        PILImage = util.get_module(
            "PIL.Image",
            required=
            "wandb.Image requires the PIL package, to get it run: pip install pillow"
        )
        if util.is_matplotlib_typename(util.get_full_typename(data)):
            buf = six.BytesIO()
            util.ensure_matplotlib_figure(data).savefig(buf)
            self.image = PILImage.open(buf)
        elif isinstance(data, PILImage.Image):
            self.image = data
        elif util.is_pytorch_tensor_typename(util.get_full_typename(data)):
            vis_util = util.get_module(
                "torchvision.utils",
                "torchvision is required to render images")
            if hasattr(data, "requires_grad") and data.requires_grad:
                data = data.detach()
            data = vis_util.make_grid(data, normalize=True)
            self.image = PILImage.fromarray(
                data.mul(255).clamp(0, 255).byte().permute(1, 2,
                                                           0).cpu().numpy())
        else:
            # Handle TF eager tensors
            if hasattr(data, "numpy"):
                data = data.numpy()
            data = data.squeeze(
            )  # get rid of trivial dimensions as a convenience
            self.image = PILImage.fromarray(self.to_uint8(data),
                                            mode=mode or self.guess_mode(data))
        self.grouping = grouping
        self.caption = caption
Exemple #5
0
def val_to_json(key, val, mode="summary", step=None):
    """Converts a wandb datatype to its JSON representation"""
    converted = val
    typename = util.get_full_typename(val)
    if util.is_matplotlib_typename(typename):
        # This handles plots with images in it because plotly doesn't support it
        # TODO: should we handle a list of plots?
        val = util.ensure_matplotlib_figure(val)
        if any(len(ax.images) > 0 for ax in val.axes):
            PILImage = util.get_module(
                "PIL.Image",
                required=
                "Logging plots with images requires pil: pip install pillow")
            buf = six.BytesIO()
            val.savefig(buf)
            val = Image(PILImage.open(buf))
        else:
            converted = util.convert_plots(val)
    elif util.is_plotly_typename(typename):
        converted = util.convert_plots(val)
    if isinstance(val, IterableMedia):
        val = [val]

    if isinstance(val, collections.Sequence) and len(val) > 0:
        is_media = [isinstance(v, IterableMedia) for v in val]
        if all(is_media):
            cwd = wandb.run.dir if wandb.run else "."
            if step is None:
                step = "summary"
            if isinstance(val[0], Image):
                converted = Image.transform(val, cwd,
                                            "{}_{}.jpg".format(key, step))
            elif isinstance(val[0], Audio):
                converted = Audio.transform(val, cwd, key, step)
            elif isinstance(val[0], Html):
                converted = Html.transform(val, cwd, key, step)
            elif isinstance(val[0], Object3D):
                converted = Object3D.transform(val, cwd, key, step)
        elif any(is_media):
            raise ValueError(
                "Mixed media types in the same list aren't supported")
    elif isinstance(val, Histogram):
        converted = Histogram.transform(val)
    elif isinstance(val, Graph):
        if mode == "history":
            raise ValueError("Graphs are only supported in summary")
        converted = Graph.transform(val)
    elif isinstance(val, Table):
        converted = Table.transform(val)
    return converted
Exemple #6
0
def val_to_json(run, key, val, step='summary'):
    """Converts a wandb datatype to its JSON representation.
    """
    converted = val
    typename = util.get_full_typename(val)

    if util.is_pandas_data_frame(val):
        assert step == 'summary', "We don't yet support DataFrames in History."
        return data_frame_to_json(val, run, key, step)
    elif util.is_matplotlib_typename(typename):
        # This handles plots with images in it because plotly doesn't support it
        # TODO: should we handle a list of plots?
        val = util.ensure_matplotlib_figure(val)
        if any(len(ax.images) > 0 for ax in val.axes):
            PILImage = util.get_module(
                "PIL.Image",
                required=
                "Logging plots with images requires pil: pip install pillow")
            buf = six.BytesIO()
            val.savefig(buf)
            val = Image(PILImage.open(buf))
        else:
            converted = plot_to_json(val)
    elif util.is_plotly_typename(typename):
        converted = plot_to_json(val)
    elif isinstance(val, collections.Sequence) and all(
            isinstance(v, WBValue) for v in val):
        # This check will break down if Image/Audio/... have child classes.
        if len(val) and isinstance(val[0], BatchableMedia) and all(
                isinstance(v, type(val[0])) for v in val):
            return val[0].seq_to_json(val, run, key, step)
        else:
            # TODO(adrian): Good idea to pass on the same key here? Maybe include
            # the array index?
            # There is a bug here: if this array contains two arrays of the same type of
            # anonymous media objects, their eventual names will collide.
            # This used to happen. The frontend doesn't handle heterogenous arrays
            #raise ValueError(
            #    "Mixed media types in the same list aren't supported")
            return [val_to_json(run, key, v, step=step) for v in val]

    if isinstance(val, WBValue):
        if isinstance(val, Media) and not val.is_bound():
            val.bind_to_run(run, key, step)
        return val.to_json(run)

    return converted