class_docstr: A class for managing Neptune experiment.
  
  Each time User creates new experiment instance of this class is created.
  It lets you manage experiment, :meth:`~neptune.experiments.Experiment.log_metric`,
  :meth:`~neptune.experiments.Experiment.log_text`,
  :meth:`~neptune.experiments.Experiment.log_image`,
  :meth:`~neptune.experiments.Experiment.set_property`,
  and much more.
  
  
  Args:
      backend (:obj:`neptune.ApiClient`): A ApiClient object
      project (:obj:`neptune.Project`): The project this experiment belongs to
      _id (:obj:`str`): Experiment id
      internal_id (:obj:`str`): internal ID
  
  Example:
      Assuming that `project` is an instance of :class:`~neptune.projects.Project`.
  
      .. code:: python3
  
          experiment = project.create_experiment()
  
  Warning:
      User should never create instances of this class manually.
      Always use: :meth:`~neptune.projects.Project.create_experiment`.
class_docstr_tok: ["A","class","for","managing","Neptune","experiment",".","Each","time","User","creates","new","experiment","instance","of","this","class","is","created",".","It","lets","you","manage","experiment",",",":","meth",":","`","~neptune.experiments.Experiment.log_metric","`",",",":","meth",":","`","~neptune.experiments.Experiment.log_text","`",",",":","meth",":","`","~neptune.experiments.Experiment.log_image","`",",",":","meth",":","`","~neptune.experiments.Experiment.set_property","`",",","and","much","more",".","Args",":","backend","(",":","obj",":","`","neptune.ApiClient","`",")",":","A","ApiClient","object","project","(",":","obj",":","`","neptune.Project","`",")",":","The","project","this","experiment","belongs","to","_id","(",":","obj",":","`","str","`",")",":","Experiment","id","internal_id","(",":","obj",":","`","str","`",")",":","internal","ID","Example",":","Assuming","that","`","project","`","is","an","instance","of",":","class",":","`","~neptune.projects.Project","`",".","..","code",":",":","python3","experiment","=","project.create_experiment","(",")","Warning",":","User","should","never","create","instances","of","this","class","manually",".","Always","use",":",":","meth",":","`","~neptune.projects.Project.create_experiment","`","."]
docstr: Log image data in Neptune
  
  | If a log with provided ``log_name`` does not exist, it is created automatically.
  | If log exists (determined by ``log_name``), then new value is appended to it.
  
  Args:
      log_name (:obj:`str`): The name of log, i.e. `bboxes`, `visualisations`, `sample_images`.
      x (:obj:`double`): Depending, whether ``y`` parameter is passed:
  
          * ``y`` not passed: The value of the log (data-point). See ``y`` parameter.
          * ``y`` passed: Index of log entry being appended. Must be strictly increasing.
  
      y (multiple types supported, optional, default is ``None``):
  
          The value of the log (data-point). Can be one of the following types:
  
          * :obj:`PIL image`
            `Pillow docs <https://pillow.readthedocs.io/en/latest/reference/Image.html#image-module>`_
          * :obj:`matplotlib.figure.Figure`
            `Matplotlib 3.1.1 docs <https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.figure.Figure.html>`_
          * :obj:`str` - path to image file
          * 2-dimensional :obj:`numpy.array` with values in the [0, 1] range - interpreted as grayscale image
          * 3-dimensional :obj:`numpy.array` with values in the [0, 1] range - behavior depends on last dimension
  
              * if last dimension is 1 - interpreted as grayscale image
              * if last dimension is 3 - interpreted as RGB image
              * if last dimension is 4 - interpreted as RGBA image
          * :obj:`torch.tensor` with values in the [0, 1] range.
              :obj:`torch.tensor`  is converted to :obj:`numpy.array` via `.numpy()` method and logged.
          * :obj:`tensorflow.tensor` with values in [0, 1] range.
              :obj:`tensorflow.tensor` is converted to :obj:`numpy.array` via `.numpy()` method and logged.
  
      image_name (:obj:`str`, optional, default is ``None``): Image name
      description (:obj:`str`, optional, default is ``None``): Image description
      timestamp (:obj:`time`, optional, default is ``None``):
          Timestamp to be associated with log entry. Must be Unix time.
          If ``None`` is passed, `time.time() <https://docs.python.org/3.6/library/time.html#time.time>`_
          (Python 3.6 example) is invoked to obtain timestamp.
  
  Example:
      Assuming that `experiment` is an instance of :class:`~neptune.experiments.Experiment`:
  
      .. code:: python3
  
          # path to image file
          experiment.log_image('bbox_images', 'pictures/image.png')
          experiment.log_image('bbox_images', x=5, 'pictures/image.png')
          experiment.log_image('bbox_images', 'pictures/image.png', image_name='difficult_case')
  
          # PIL image
          img = PIL.Image.new('RGB', (60, 30), color = 'red')
          experiment.log_image('fig', img)
  
          # 2d numpy array
          array = numpy.random.rand(300, 200)*255
          experiment.log_image('fig', array)
  
          # 3d grayscale array
          array = numpy.random.rand(300, 200, 1)*255
          experiment.log_image('fig', array)
  
          # 3d RGB array
          array = numpy.random.rand(300, 200, 3)*255
          experiment.log_image('fig', array)
  
          # 3d RGBA array
          array = numpy.random.rand(300, 200, 4)*255
          experiment.log_image('fig', array)
  
          # torch tensor
          tensor = torch.rand(10, 20)
          experiment.log_image('fig', tensor)
  
          # tensorflow tensor
          tensor = tensorflow.random.uniform(shape=[10, 20])
          experiment.log_image('fig', tensor)
  
          # matplotlib figure example 1
          from matplotlib import pyplot
          pyplot.plot([1, 2, 3, 4])
          pyplot.ylabel('some numbers')
          experiment.log_image('plots', plt.gcf())
  
          # matplotlib figure example 2
          from matplotlib import pyplot
          import numpy
  
          numpy.random.seed(19680801)
          data = numpy.random.randn(2, 100)
  
          figure, axs = pyplot.subplots(2, 2, figsize=(5, 5))
          axs[0, 0].hist(data[0])
          axs[1, 0].scatter(data[0], data[1])
          axs[0, 1].plot(data[0], data[1])
          axs[1, 1].hist2d(data[0], data[1])
  
          experiment.log_image('diagrams', figure)
  
  Note:
      For efficiency, logs are uploaded in batches via a queue.
      Hence, if you log a lot of data, you may experience slight delays in Neptune web application.
  Note:
      Passing ``x`` coordinate as NaN or +/-inf causes this log entry to be ignored.
      Warning is printed to ``stdout``.
  Warning:
      Only images up to 15MB are supported. Larger files will not be logged to Neptune.
docstr_tok: ["Log","image","data","in","Neptune","|","If","a","log","with","provided","``","log_name","``","does","not","exist",",","it","is","created","automatically",".","|","If","log","exists","(","determined","by","``","log_name","``",")",",","then","new","value","is","appended","to","it",".","Args",":","log_name","(",":","obj",":","`","str","`",")",":","The","name","of","log",",","i.e",".","`","bboxes","`",",","`","visualisations","`",",","`","sample_images","`",".","x","(",":","obj",":","`","double","`",")",":","Depending",",","whether","``","y","``","parameter","is","passed",":","*","``","y","``","not","passed",":","The","value","of","the","log","(","data-point",")",".","See","``","y","``","parameter",".","*","``","y","``","passed",":","Index","of","log","entry","being","appended",".","Must","be","strictly","increasing",".","y","(","multiple","types","supported",",","optional",",","default","is","``","None","``",")",":","The","value","of","the","log","(","data-point",")",".","Can","be","one","of","the","following","types",":","*",":","obj",":","`","PIL","image","`","`","Pillow","docs","<","https",":","\/\/pillow.readthedocs.io\/en\/latest\/reference\/Image.html","#","image-module",">","`","_","*",":","obj",":","`","matplotlib.figure.Figure","`","`","Matplotlib","3.1.1","docs","<","https",":","\/\/matplotlib.org\/3.1.1\/api\/_as_gen\/matplotlib.figure.Figure.html",">","`","_","*",":","obj",":","`","str","`","-","path","to","image","file","*","2-dimensional",":","obj",":","`","numpy.array","`","with","values","in","the","[","0",",","1","]","range","-","interpreted","as","grayscale","image","*","3-dimensional",":","obj",":","`","numpy.array","`","with","values","in","the","[","0",",","1","]","range","-","behavior","depends","on","last","dimension","*","if","last","dimension","is","1","-","interpreted","as","grayscale","image","*","if","last","dimension","is","3","-","interpreted","as","RGB","image","*","if","last","dimension","is","4","-","interpreted","as","RGBA","image","*",":","obj",":","`","torch.tensor","`","with","values","in","the","[","0",",","1","]","range",".",":","obj",":","`","torch.tensor","`","is","converted","to",":","obj",":","`","numpy.array","`","via","`",".numpy","(",")","`","method","and","logged",".","*",":","obj",":","`","tensorflow.tensor","`","with","values","in","[","0",",","1","]","range",".",":","obj",":","`","tensorflow.tensor","`","is","converted","to",":","obj",":","`","numpy.array","`","via","`",".numpy","(",")","`","method","and","logged",".","image_name","(",":","obj",":","`","str","`",",","optional",",","default","is","``","None","``",")",":","Image","name","description","(",":","obj",":","`","str","`",",","optional",",","default","is","``","None","``",")",":","Image","description","timestamp","(",":","obj",":","`","time","`",",","optional",",","default","is","``","None","``",")",":","Timestamp","to","be","associated","with","log","entry",".","Must","be","Unix","time",".","If","``","None","``","is","passed",",","`","time.time","(",")","<","https",":","\/\/docs.python.org\/3.6\/library\/time.html","#","time.time",">","`","_","(","Python","3.6","example",")","is","invoked","to","obtain","timestamp",".","Example",":","Assuming","that","`","experiment","`","is","an","instance","of",":","class",":","`","~neptune.experiments.Experiment","`",":","..","code",":",":","python3","#","path","to","image","file","experiment.log_image","(","'bbox_images","'",",","'pictures\/image.png","'",")","experiment.log_image","(","'bbox_images","'",",","x=5",",","'pictures\/image.png","'",")","experiment.log_image","(","'bbox_images","'",",","'pictures\/image.png","'",",","image_name='difficult_case","'",")","#","PIL","image","img","=","PIL.Image.new","(","'RGB","'",",","(","60",",","30",")",",","color","=","'red","'",")","experiment.log_image","(","'fig","'",",","img",")","#","2d","numpy","array","array","=","numpy.random.rand","(","300",",","200",")","*","255","experiment.log_image","(","'fig","'",",","array",")","#","3d","grayscale","array","array","=","numpy.random.rand","(","300",",","200",",","1",")","*","255","experiment.log_image","(","'fig","'",",","array",")","#","3d","RGB","array","array","=","numpy.random.rand","(","300",",","200",",","3",")","*","255","experiment.log_image","(","'fig","'",",","array",")","#","3d","RGBA","array","array","=","numpy.random.rand","(","300",",","200",",","4",")","*","255","experiment.log_image","(","'fig","'",",","array",")","#","torch","tensor","tensor","=","torch.rand","(","10",",","20",")","experiment.log_image","(","'fig","'",",","tensor",")","#","tensorflow","tensor","tensor","=","tensorflow.random.uniform","(","shape=","[","10",",","20","]",")","experiment.log_image","(","'fig","'",",","tensor",")","#","matplotlib","figure","example","1","from","matplotlib","import","pyplot","pyplot.plot","(","[","1",",","2",",","3",",","4","]",")","pyplot.ylabel","(","'some","numbers","'",")","experiment.log_image","(","'plots","'",",","plt.gcf","(",")",")","#","matplotlib","figure","example","2","from","matplotlib","import","pyplot","import","numpy","numpy.random.seed","(","19680801",")","data","=","numpy.random.randn","(","2",",","100",")","figure",",","axs","=","pyplot.subplots","(","2",",","2",",","figsize=","(","5",",","5",")",")","axs","[","0",",","0","]",".hist","(","data","[","0","]",")","axs","[","1",",","0","]",".scatter","(","data","[","0","]",",","data","[","1","]",")","axs","[","0",",","1","]",".plot","(","data","[","0","]",",","data","[","1","]",")","axs","[","1",",","1","]",".hist2d","(","data","[","0","]",",","data","[","1","]",")","experiment.log_image","(","'diagrams","'",",","figure",")","Note",":","For","efficiency",",","logs","are","uploaded","in","batches","via","a","queue",".","Hence",",","if","you","log","a","lot","of","data",",","you","may","experience","slight","delays","in","Neptune","web","application",".","Note",":","Passing","``","x","``","coordinate","as","NaN","or","+\/-inf","causes","this","log","entry","to","be","ignored",".","Warning","is","printed","to","``","stdout","``",".","Warning",":","Only","images","up","to","15MB","are","supported",".","Larger","files","will","not","be","logged","to","Neptune","."]
code: def log_image(
      self,
      log_name,
      x,
      y=None,
      image_name=None,
      description=None,
      timestamp=None,
  ):
      """Log image data in Neptune
  
      | If a log with provided ``log_name`` does not exist, it is created automatically.
      | If log exists (determined by ``log_name``), then new value is appended to it.
  
      Args:
          log_name (:obj:`str`): The name of log, i.e. `bboxes`, `visualisations`, `sample_images`.
          x (:obj:`double`): Depending, whether ``y`` parameter is passed:
  
              * ``y`` not passed: The value of the log (data-point). See ``y`` parameter.
              * ``y`` passed: Index of log entry being appended. Must be strictly increasing.
  
          y (multiple types supported, optional, default is ``None``):
  
              The value of the log (data-point). Can be one of the following types:
  
              * :obj:`PIL image`
                `Pillow docs <https://pillow.readthedocs.io/en/latest/reference/Image.html#image-module>`_
              * :obj:`matplotlib.figure.Figure`
                `Matplotlib 3.1.1 docs <https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.figure.Figure.html>`_
              * :obj:`str` - path to image file
              * 2-dimensional :obj:`numpy.array` with values in the [0, 1] range - interpreted as grayscale image
              * 3-dimensional :obj:`numpy.array` with values in the [0, 1] range - behavior depends on last dimension
  
                  * if last dimension is 1 - interpreted as grayscale image
                  * if last dimension is 3 - interpreted as RGB image
                  * if last dimension is 4 - interpreted as RGBA image
              * :obj:`torch.tensor` with values in the [0, 1] range.
                  :obj:`torch.tensor`  is converted to :obj:`numpy.array` via `.numpy()` method and logged.
              * :obj:`tensorflow.tensor` with values in [0, 1] range.
                  :obj:`tensorflow.tensor` is converted to :obj:`numpy.array` via `.numpy()` method and logged.
  
          image_name (:obj:`str`, optional, default is ``None``): Image name
          description (:obj:`str`, optional, default is ``None``): Image description
          timestamp (:obj:`time`, optional, default is ``None``):
              Timestamp to be associated with log entry. Must be Unix time.
              If ``None`` is passed, `time.time() <https://docs.python.org/3.6/library/time.html#time.time>`_
              (Python 3.6 example) is invoked to obtain timestamp.
  
      Example:
          Assuming that `experiment` is an instance of :class:`~neptune.experiments.Experiment`:
  
          .. code:: python3
  
              # path to image file
              experiment.log_image('bbox_images', 'pictures/image.png')
              experiment.log_image('bbox_images', x=5, 'pictures/image.png')
              experiment.log_image('bbox_images', 'pictures/image.png', image_name='difficult_case')
  
              # PIL image
              img = PIL.Image.new('RGB', (60, 30), color = 'red')
              experiment.log_image('fig', img)
  
              # 2d numpy array
              array = numpy.random.rand(300, 200)*255
              experiment.log_image('fig', array)
  
              # 3d grayscale array
              array = numpy.random.rand(300, 200, 1)*255
              experiment.log_image('fig', array)
  
              # 3d RGB array
              array = numpy.random.rand(300, 200, 3)*255
              experiment.log_image('fig', array)
  
              # 3d RGBA array
              array = numpy.random.rand(300, 200, 4)*255
              experiment.log_image('fig', array)
  
              # torch tensor
              tensor = torch.rand(10, 20)
              experiment.log_image('fig', tensor)
  
              # tensorflow tensor
              tensor = tensorflow.random.uniform(shape=[10, 20])
              experiment.log_image('fig', tensor)
  
              # matplotlib figure example 1
              from matplotlib import pyplot
              pyplot.plot([1, 2, 3, 4])
              pyplot.ylabel('some numbers')
              experiment.log_image('plots', plt.gcf())
  
              # matplotlib figure example 2
              from matplotlib import pyplot
              import numpy
  
              numpy.random.seed(19680801)
              data = numpy.random.randn(2, 100)
  
              figure, axs = pyplot.subplots(2, 2, figsize=(5, 5))
              axs[0, 0].hist(data[0])
              axs[1, 0].scatter(data[0], data[1])
              axs[0, 1].plot(data[0], data[1])
              axs[1, 1].hist2d(data[0], data[1])
  
              experiment.log_image('diagrams', figure)
  
      Note:
          For efficiency, logs are uploaded in batches via a queue.
          Hence, if you log a lot of data, you may experience slight delays in Neptune web application.
      Note:
          Passing ``x`` coordinate as NaN or +/-inf causes this log entry to be ignored.
          Warning is printed to ``stdout``.
      Warning:
          Only images up to 15MB are supported. Larger files will not be logged to Neptune.
      """
      x, y = self._get_valid_x_y(x, y)
  
      if x is not None and is_nan_or_inf(x):
          x = None
  
      image_content = get_image_content(y)
      if len(image_content) > self.IMAGE_SIZE_LIMIT_MB * 1024 * 1024:
          _logger.warning(
              "Your image is larger than %dMB. Neptune supports logging images smaller than %dMB. "
              "Resize or increase compression of this image",
              self.IMAGE_SIZE_LIMIT_MB,
              self.IMAGE_SIZE_LIMIT_MB,
          )
          image_content = None
  
      input_image = dict(name=image_name, description=description)
      if image_content:
          input_image["data"] = base64.b64encode(image_content).decode(
              "utf-8"
          )
  
      if x is not None and is_nan_or_inf(x):
          _logger.warning(
              "Invalid metric x-coordinate: %s for channel %s. "
              "Metrics with nan or +/-inf x-coordinates will not be sent to server",
              x,
              log_name,
          )
      else:
          value = ChannelValue(
              x, dict(image_value=input_image), timestamp
          )
          self._channels_values_sender.send(
              log_name, ChannelType.IMAGE.value, value
          )
  
imports: import base64
  import logging
  import traceback
  import pandas
  import six
  from pandas.errors import EmptyDataError
  from neptune.common.experiments import LegacyExperiment
  from neptune.common.utils import align_channels_on_x, is_float, is_nan_or_inf
  from neptune.legacy.api_exceptions import ChannelDoesNotExist, ExperimentAlreadyFinished
  from neptune.legacy.exceptions import InvalidChannelValue, NeptuneIncorrectImportException, NoChannelValue
  from neptune.legacy.internal.channels.channels import ChannelNamespace, ChannelType, ChannelValue
  from neptune.legacy.internal.channels.channels_values_sender import ChannelsValuesSender
  from neptune.legacy.internal.execution.execution_context import ExecutionContext
  from neptune.legacy.internal.utils.deprecation import legacy_client_deprecation
  from neptune.legacy.internal.utils.image import get_image_content
label_desc: Use image node_id 24 for calling the Experiment obj's underlying member method code with example usage: obj.log_image(log_name, x, y, image_name, description, timestamp) without return types