Add Logger.matplotlib_force_report_non_interactive()

This commit is contained in:
allegroai 2021-05-19 15:24:47 +03:00
parent 8fb4fb2b5e
commit 016a5c2d71
3 changed files with 38 additions and 6 deletions

View File

@ -839,6 +839,11 @@ class Reporter(InterfaceBase, AbstractContextManager, SetupUploadMixin, AsyncMan
) )
self._report(ev) self._report(ev)
@classmethod
def matplotlib_force_report_non_interactive(cls, force):
from clearml.binding.matplotlib_bind import PatchedMatplotlib
PatchedMatplotlib.force_report_as_image(force=force)
@classmethod @classmethod
def _normalize_name(cls, name): def _normalize_name(cls, name):
return name return name

View File

@ -34,6 +34,7 @@ class PatchedMatplotlib:
_recursion_guard = {} _recursion_guard = {}
_matplot_major_version = 0 _matplot_major_version = 0
_matplot_minor_version = 0 _matplot_minor_version = 0
_force_report_as_image = False
_logger_started_reporting = False _logger_started_reporting = False
_matplotlib_reported_titles = set() _matplotlib_reported_titles = set()
@ -49,6 +50,16 @@ class PatchedMatplotlib:
pass pass
return bypass return bypass
@staticmethod
def force_report_as_image(force):
# type: (bool) -> None
"""
Set force_report_as_image. If True all matplotlib are always converted to images
Otherwise we try to convert them into interactive plotly plots.
:param force: True force
"""
PatchedMatplotlib._force_report_as_image = bool(force)
@staticmethod @staticmethod
def patch_matplotlib(): def patch_matplotlib():
# only once # only once
@ -361,18 +372,21 @@ class PatchedMatplotlib:
# if auto bind (i.e. plt.show) and plot already displayed explicitly, do nothing. # if auto bind (i.e. plt.show) and plot already displayed explicitly, do nothing.
return return
if PatchedMatplotlib._force_report_as_image:
force_save_as_image = True
# convert to plotly # convert to plotly
image = None image = None
plotly_dict = None plotly_dict = None
image_format = 'jpeg' image_format = 'jpeg'
fig_dpi = 300 fig_dpi = 300
if force_save_as_image or report_as_debug_sample: 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. # if this is an image, store as is.
fig_dpi = None if report_as_debug_sample else 300 image_format = force_save_as_image if isinstance(force_save_as_image, str) else 'png'
force_save_as_image = force_save_as_image \
if force_save_as_image and isinstance(force_save_as_image, str) else 'png'
if isinstance(force_save_as_image, str):
image_format = force_save_as_image
else: else:
image_format = 'svg' image_format = 'svg'
# protect with lock, so we support multiple threads using the same renderer # protect with lock, so we support multiple threads using the same renderer

View File

@ -1167,6 +1167,19 @@ class Logger(object):
""" """
cls._tensorboard_single_series_per_graph = single_series cls._tensorboard_single_series_per_graph = single_series
@classmethod
def matplotlib_force_report_non_interactive(cls, force):
# type: (bool) -> None
"""
If True all matplotlib are always converted to non interactive static plots (images), appearing in under
the Plots section. If False (default), matplotlib figures are converted into interactive web UI plotly
figures, in case figure conversion fails, it defaults to non-interactive plots.
:param force: If True all matplotlib figures are converted automatically to non-interactive plots.
"""
from clearml.backend_interface.metrics import Reporter
Reporter.matplotlib_force_report_non_interactive(force=force)
@classmethod @classmethod
def _remove_std_logger(cls): def _remove_std_logger(cls):
# noinspection PyBroadException # noinspection PyBroadException