code: def _report_figure(
      force_save_as_image=False,
      report_as_debug_sample=False,
      stored_figure=None,
      set_active=True,
      specific_fig=None,
      title=None,
      series=None,
      iter=None,
      reporter=None,
      logger=None,
  ):
      # get the main task
      if (
          not PatchedMatplotlib._current_task
          and not reporter
          and not logger
      ):
          return
  
      # check if this is explicit reporting
      is_explicit = reporter and logger
  
      # noinspection PyProtectedMember
      reporter = reporter or PatchedMatplotlib._current_task._reporter
      if not reporter:
          return
      logger = logger or PatchedMatplotlib._current_task.get_logger()
      if not logger:
          return
  
      # make sure we have matplotlib ready
      PatchedMatplotlib._update_matplotlib_version()
  
      # noinspection PyBroadException
      try:
          import matplotlib.pyplot as plt
          from matplotlib import _pylab_helpers
  
          if specific_fig is None:
              # store the figure object we just created (if it is not already there)
              stored_figure = (
                  stored_figure or _pylab_helpers.Gcf.get_active()
              )
              if not stored_figure:
                  # nothing for us to do
                  return
              # check if this is an imshow
              if (
                  getattr(stored_figure, "_trains_is_imshow", None)
                  is not None
              ):
                  # flag will be cleared when calling clf() (object will be replaced)
                  stored_figure._trains_is_imshow = max(
                      0, stored_figure._trains_is_imshow - 1
                  )
                  report_as_debug_sample = True
              # get current figure
              mpl_fig = stored_figure.canvas.figure  # plt.gcf()
          else:
              mpl_fig = specific_fig
  
          if is_explicit:
              # marked displayed explicitly
              mpl_fig._trains_explicit = True
          elif getattr(mpl_fig, "_trains_explicit", False):
              # if auto bind (i.e. plt.show) and plot already displayed explicitly, do nothing.
              return
  
          if PatchedMatplotlib._force_report_as_image:
              force_save_as_image = True
  
          # if we have subplots, we will probably fail in conversion, so we just store as image
          if (
              not report_as_debug_sample
              and not force_save_as_image
              and mpl_fig
              and getattr(mpl_fig, "axes", None)
              and len(mpl_fig.axes) > 1
          ):
              force_save_as_image = True
  
          # convert to plotly
          image = None
          plotly_dict = None
          image_format = "jpeg"
          fig_dpi = 300
          if report_as_debug_sample:
              fig_dpi = None
              image_format = (
                  force_save_as_image
                  if force_save_as_image
                  and isinstance(force_save_as_image, str)
                  else "jpeg"
              )
          elif force_save_as_image:
              # if this is an image, store as is.
              image_format = (
                  force_save_as_image
                  if isinstance(force_save_as_image, str)
                  else "png"
              )
          else:
              image_format = "svg"
              # protect with lock, so we support multiple threads using the same renderer
              PatchedMatplotlib._lock_renderer.acquire()
              # noinspection PyBroadException
              try:
  
                  def our_mpl_to_plotly(fig):
                      if (
                          not PatchedMatplotlib._update_plotly_renderers()
                      ):
                          return None
  
                      plotly_renderer = (
                          PatchedMatplotlib._matplotlylib.PlotlyRenderer()
                      )
                      PatchedMatplotlib._matplotlylib.Exporter(
                          plotly_renderer, close_mpl=False
                      ).run(fig)
  
                      def process_tick_text(ticks, axes, val_index):
                          if not ticks:
                              return
                          # noinspection PyBroadException
                          try:
                              # check if all values can be cast to float
                              _ = [
                                  float(t.get_text().replace("−", "-"))
                                  for t in ticks
                              ]
                          except Exception:
                              # noinspection PyBroadException
                              try:
  
                                  def convert_latex_math_powers_to_html(
                                      text,
                                  ):
                                      # noinspection PyBroadException
                                      try:
                                          if (
                                              not text
                                              or not text.startswith(
                                                  "$\\mathdefault{"
                                              )
                                              or not text.endswith(
                                                  "}}$"
                                              )
                                          ):
                                              return text
                                          numbers = text[
                                              len(
                                                  "$\\mathdefault{"
                                              ) : -len("}}$")
                                          ].split("^{")
                                          if len(numbers) != 2:
                                              return text
                                          base, exp_ = (
                                              numbers[0],
                                              numbers[1],
                                          )
                                          return (
                                              "{}<sup>{}</sup>".format(
                                                  base, exp_
                                              )
                                          )
                                      except Exception:
                                          return text
  
                                  _axis = next(
                                      x
                                      for x in axes
                                      if x
                                      in plotly_renderer.plotly_fig[
                                          "layout"
                                      ]
                                  )
                                  plotly_renderer.plotly_fig["layout"][
                                      _axis
                                  ].update(
                                      {
                                          "ticktext": [
                                              convert_latex_math_powers_to_html(
                                                  t.get_text()
                                              )
                                              for t in ticks
                                          ],
                                          "tickvals": [
                                              t.get_position()[
                                                  val_index
                                              ]
                                              for t in ticks
                                          ],
                                      }
                                  )
                                  if (
                                      plotly_renderer.plotly_fig[
                                          "layout"
                                      ][_axis].get("type")
                                      == "linear"
                                  ):
                                      plotly_renderer.plotly_fig[
                                          "layout"
                                      ][_axis].pop("type", None)
                              except Exception:
                                  pass
  
                      process_tick_text(
                          list(
                              plotly_renderer.current_mpl_ax.get_xticklabels()
                          ),
                          ("xaxis", "xaxis0", "xaxis1"),
                          0,
                      )
                      process_tick_text(
                          list(
                              plotly_renderer.current_mpl_ax.get_yticklabels()
                          ),
                          ("yaxis", "yaxis0", "yaxis1"),
                          1,
                      )
                      # noinspection PyBroadException
                      try:
                          # check if we have a 3d plot
                          if (
                              "zaxis"
                              in plotly_renderer.plotly_fig.get(
                                  "layout", {}
                              )
                              or "zaxis0"
                              in plotly_renderer.plotly_fig.get(
                                  "layout", {}
                              )
                              or "zaxis1"
                              in plotly_renderer.plotly_fig.get(
                                  "layout", {}
                              )
                              or len(
                                  plotly_renderer.plotly_fig.get(
                                      "data", [{}]
                                  )[0].get("z", [])
                              )
                              > 0
                          ):
                              process_tick_text(
                                  list(
                                      plotly_renderer.current_mpl_ax.get_zticklabels()
                                  ),
                                  ("zaxis", "zaxis0", "zaxis1"),
                                  2,
                              )
  
                              # rotate the X axis -90 degrees such that it matches matplotlib
                              plotly_renderer.plotly_fig.setdefault(
                                  "layout", {}
                              ).setdefault("scene", {}).setdefault(
                                  "camera", {}
                              ).setdefault(
                                  "eye", {}
                              ).setdefault(
                                  "x", -1
                              )
  
                              # reverse the X and Y axes such that they match matplotlib
                              plotly_renderer.plotly_fig.setdefault(
                                  "layout", {}
                              ).setdefault("scene", {}).setdefault(
                                  "xaxis", {}
                              ).setdefault(
                                  "autorange", "reversed"
                              )
  
                              plotly_renderer.plotly_fig.setdefault(
                                  "layout", {}
                              ).setdefault("scene", {}).setdefault(
                                  "yaxis", {}
                              ).setdefault(
                                  "autorange", "reversed"
                              )
                      except Exception:
                          pass
  
                      # try to bring back legend
                      # noinspection PyBroadException
                      try:
                          if plotly_renderer.plotly_fig.get(
                              "layout", {}
                          ).get(
                              "showlegend"
                          ) and plotly_renderer.plotly_fig.get(
                              "data"
                          ):
                              # the legend names is the upper half of the data points:
                              lines_ = plotly_renderer.plotly_fig[
                                  "data"
                              ]
                              half_mark = len(lines_) // 2
                              if len(lines_) % 2 == 0 and all(
                                  not ln.get("x") and not ln.get("y")
                                  for ln in lines_[half_mark:]
                              ):
                                  for i, line in enumerate(
                                      lines_[:half_mark]
                                  ):
                                      line["name"] = lines_[
                                          i + half_mark
                                      ].get("name")
                      except Exception:
                          pass
  
                      # let plotly deal with the range in realtime (otherwise there is no real way to change it to
                      if (
                          not plotly_renderer.plotly_fig.get(
                              "layout", {}
                          )
                          .get("xaxis", {})
                          .pop("custom_range", False)
                      ):
                          plotly_renderer.plotly_fig.get(
                              "layout", {}
                          ).get("xaxis", {}).pop("range", None)
                      if (
                          not plotly_renderer.plotly_fig.get(
                              "layout", {}
                          )
                          .get("yaxis", {})
                          .pop("custom_range", False)
                      ):
                          plotly_renderer.plotly_fig.get(
                              "layout", {}
                          ).get("yaxis", {}).pop("range", None)
                      return deepcopy(plotly_renderer.plotly_fig)
  
                  plotly_dict = our_mpl_to_plotly(mpl_fig)
  
                  # # protect against very large plots, convert to png
                  # # noinspection PyBroadException
                  # try:
                  #     num_points = sum([max(len(d.get('x', [])), len(d.get('y', [])))
                  #                       for d in plotly_dict.get('data', [])])
                  #     if num_points > 100000:
                  #         plotly_dict = None
                  #         image_format = 'png'
                  #         fig_dpi = 300
                  # except Exception:
                  #     pass
  
              except Exception as ex:
                  # this was an image, change format to png
                  image_format = (
                      "jpeg" if "selfie" in str(ex) else "png"
                  )
                  fig_dpi = 300
              finally:
                  PatchedMatplotlib._lock_renderer.release()
  
          # plotly could not serialize the plot, we should convert to image
          if not plotly_dict:
              plotly_dict = None
              # noinspection PyBroadException
              try:
                  # first try SVG if we fail then fallback to png
                  buffer_ = BytesIO()
                  a_plt = (
                      specific_fig if specific_fig is not None else plt
                  )
                  if PatchedMatplotlib._matplot_major_version < 3:
                      a_plt.savefig(
                          buffer_,
                          dpi=fig_dpi,
                          format=image_format,
                          bbox_inches="tight",
                          pad_inches=0,
                          frameon=False,
                      )
                  else:
                      a_plt.savefig(
                          buffer_,
                          dpi=fig_dpi,
                          format=image_format,
                          bbox_inches="tight",
                          pad_inches=0,
                          facecolor=None,
                      )
                  buffer_.seek(0)
              except Exception:
                  image_format = "png"
                  buffer_ = BytesIO()
                  a_plt = (
                      specific_fig if specific_fig is not None else plt
                  )
                  if PatchedMatplotlib._matplot_major_version < 3:
                      a_plt.savefig(
                          buffer_,
                          dpi=fig_dpi,
                          format=image_format,
                          bbox_inches="tight",
                          pad_inches=0,
                          frameon=False,
                      )
                  else:
                      a_plt.savefig(
                          buffer_,
                          dpi=fig_dpi,
                          format=image_format,
                          bbox_inches="tight",
                          pad_inches=0,
                          facecolor=None,
                      )
                  buffer_.seek(0)
              fd, image = mkstemp(suffix="." + image_format)
              with open(fd, "wb") as f:
                  f.write(buffer_.read())
  
          # check if we need to restore the active object
          if (
              set_active
              and not _pylab_helpers.Gcf.get_active()
              and stored_figure
          ):
              _pylab_helpers.Gcf.set_active(stored_figure)
  
          last_iteration = (
              iter
              if iter is not None
              else PatchedMatplotlib._get_last_iteration()
          )
  
          report_as_debug_sample = report_as_debug_sample or (
              not plotly_dict
              and not PatchedMatplotlib._support_image_plot
          )
  
          if not title:
              if mpl_fig.texts:
                  plot_title = mpl_fig.texts[0].get_text()
              else:
                  gca = mpl_fig.gca()
                  plot_title = (
                      gca.title.get_text() if gca.title else None
                  )
  
              if plot_title:
                  title = PatchedMatplotlib._enforce_unique_title_per_iteration(
                      plot_title, last_iteration
                  )
              elif report_as_debug_sample:
                  PatchedMatplotlib._global_image_counter += 1
                  title = "untitled {:02d}".format(
                      PatchedMatplotlib._global_image_counter
                      % PatchedMatplotlib._get_global_image_counter_limit()
                  )
              else:
                  PatchedMatplotlib._global_plot_counter += 1
                  title = "untitled {:02d}".format(
                      PatchedMatplotlib._global_plot_counter
                      % PatchedMatplotlib._get_global_image_counter_limit()
                  )
  
          # by now we should have a title, if the iteration was known list us as globally reported.
          # we later use it to check if externally someone was actually reporting iterations
          if iter is None:
              PatchedMatplotlib._matplotlib_reported_titles.add(title)
  
          # remove borders and size, we should let the web take care of that
          if plotly_dict:
              # send the plot event
              if not plotly_dict.get("layout"):
                  plotly_dict["layout"] = {}
              plotly_dict["layout"]["margin"] = {}
              plotly_dict["layout"]["autosize"] = True
              plotly_dict["layout"]["height"] = None
              plotly_dict["layout"]["width"] = None
              plotly_dict["layout"]["title"] = series or title
  
              reporter.report_plot(
                  title=title,
                  series=series or "plot",
                  plot=plotly_dict,
                  iter=last_iteration,
              )
          else:
              # this is actually a failed plot, we should put it under plots:
              # currently disabled
              if report_as_debug_sample:
                  logger.report_image(
                      title=title,
                      series=series or "plot image",
                      local_path=image,
                      delete_after_upload=True,
                      iteration=last_iteration,
                  )
              else:
                  # noinspection PyProtectedMember
                  logger._report_image_plot_and_upload(
                      title=title,
                      series=series or "plot image",
                      path=image,
                      delete_after_upload=True,
                      iteration=last_iteration,
                  )
      except Exception:
          # plotly failed
          pass
  
imports: import sys
  import threading
  from copy import deepcopy
  from tempfile import mkstemp
  import six
  from six import BytesIO
  from .import_bind import PostImportHookPatching
  from ..config import running_remotely
  from ..debugging.log import LoggerRoot
  from ..utilities.resource_monitor import ResourceMonitor
label_desc: Use image node_id 13 for calling the PatchedMatplotlib obj's underlying member method code with example usage: obj._report_figure(force_save_as_image, report_as_debug_sample, stored_figure, set_active, specific_fig, title, series, iter, reporter, logger) and returns: deepcopy, None, str, text, text, text