From 0d98f1cc065abaa99a2285b87e4e58ccc1f2faf3 Mon Sep 17 00:00:00 2001 From: lberrada Date: Sat, 27 Jan 2018 17:40:44 +0000 Subject: [PATCH 1/5] simple text formatting --- logger/plotter.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/logger/plotter.py b/logger/plotter.py index 52fa558..43cf306 100644 --- a/logger/plotter.py +++ b/logger/plotter.py @@ -98,8 +98,13 @@ def plot_metric(self, metric): cache.clear() def plot_config(self, config): + config = dict((str(k), v) for (k, v) in config.items()) # format dictionary with pretty print - pp = pprint.PrettyPrinter(indent=4) + pp = pprint.PrettyPrinter(indent=4, width=1) msg = pp.pformat(config) + # format with html + msg = msg.replace('{', '') + msg = msg.replace('}', '') + msg = msg.replace('\n', '
') # display dict on visdom self.viz.text(msg) From e6ec03e137e585f979490c48a12b7ebd6dc6a563 Mon Sep 17 00:00:00 2001 From: lberrada Date: Sat, 27 Jan 2018 18:25:16 +0000 Subject: [PATCH 2/5] allowing to pass opts to visdom for each window - settings are saved with experiment --- examples/example.py | 4 ++++ logger/plotter.py | 22 ++++++++++++++++------ logger/xp.py | 4 ++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/examples/example.py b/examples/example.py index 5ddad1f..b73aaae 100644 --- a/examples/example.py +++ b/examples/example.py @@ -69,6 +69,10 @@ def oracle(data, target): xp.AvgMetric(tag="test", name="acc1") xp.AvgMetric(tag="test", name="acck") +xp.plotter.set_win_opts(name="acc1", opts={'title': 'Accuracy@1'}) +xp.plotter.set_win_opts(name="acck", opts={'title': 'Accuracy@k'}) +xp.plotter.set_win_opts(name="loss", opts={'title': 'Loss'}) + #---------------------------------------------------------- # Training #---------------------------------------------------------- diff --git a/logger/plotter.py b/logger/plotter.py index 43cf306..a7c0ce1 100644 --- a/logger/plotter.py +++ b/logger/plotter.py @@ -48,20 +48,31 @@ def __init__(self, xp, visdom_opts, xlabel): self.viz = visdom.Visdom(**visdom_opts) self.xlabel = None if xlabel is None else str(xlabel) self.windows = {} + self.windows_opts = defaultdict(dict) self.append = {} self.cache = defaultdict(Cache) + def set_win_opts(self, name, opts): + self.windows_opts[name] = opts + def _plot_xy(self, name, tag, x, y, time_idx=True): """ Creates a window if it does not exist yet. Returns True if data has been sent successfully, False otherwise. """ if name not in list(self.windows.keys()): - if self.xlabel is None: - xlabel = 'Time (s)' if time_idx else 'Index' + opts = self.windows_opts[name] + if 'xlabel' in opts: + pass + elif self.xlabel is not None: + opts['xlabel'] = self.xlabel else: - xlabel = self.xlabel - opts = {'legend': [tag], 'title': name, 'xlabel': xlabel} + opts['xlabel'] = 'Time (s)' if time_idx else 'Index' + + if 'legend' not in opts and tag != 'default': + opts['legend'] = [tag] + if 'title' not in opts: + opts['title'] = name self.windows[name] = self.viz.line(Y=y, X=x, opts=opts) return True else: @@ -91,8 +102,7 @@ def plot_metric(self, metric): name, tag = metric.name, metric.tag cache = self.cache[metric.name_id()] cache.update(metric) - sent = self._plot_xy(name, tag, cache.x, cache.y, - metric.time_idx) + sent = self._plot_xy(name, tag, cache.x, cache.y, metric.time_idx) # clear cache if data has been sent successfully if sent: cache.clear() diff --git a/logger/xp.py b/logger/xp.py index a0465d1..9cfc818 100644 --- a/logger/xp.py +++ b/logger/xp.py @@ -198,6 +198,8 @@ def get_var_dict(self): var_dict['name'] = self.name var_dict['name_and_dir'] = self.name_and_dir var_dict['date_and_time'] = self.date_and_time + if self.use_visdom: + var_dict['visdom_win_opts'] = self.plotter.windows_opts return var_dict def to_pickle(self, filename): @@ -224,6 +226,8 @@ def from_json(self, filename): def to_visdom(self, visdom_opts=None, xlabel=None): self.plotter = Plotter(self, visdom_opts, xlabel) + for (name, opts) in self.visdom_win_opts.items(): + self.plotter.set_win_opts(name, opts) self.plotter.plot_xp(self) From 406eead0def1128967e1a8619d23feea68b58f39 Mon Sep 17 00:00:00 2001 From: lberrada Date: Sat, 27 Jan 2018 19:02:33 +0000 Subject: [PATCH 3/5] check for existence of visdom_win_opts attribute --- logger/xp.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/logger/xp.py b/logger/xp.py index 9cfc818..98b2eb1 100644 --- a/logger/xp.py +++ b/logger/xp.py @@ -226,8 +226,10 @@ def from_json(self, filename): def to_visdom(self, visdom_opts=None, xlabel=None): self.plotter = Plotter(self, visdom_opts, xlabel) - for (name, opts) in self.visdom_win_opts.items(): - self.plotter.set_win_opts(name, opts) + # restore visdom options that have been saved (if experiment loaded from file) + if hasattr(self, 'visdom_win_opts'): + for (name, opts) in self.visdom_win_opts.items(): + self.plotter.set_win_opts(name, opts) self.plotter.plot_xp(self) From e6d0b3f6a76f2cf0ebf03ed73b70c6b214110c3e Mon Sep 17 00:00:00 2001 From: lberrada Date: Sat, 3 Feb 2018 14:03:23 +0000 Subject: [PATCH 4/5] small fix when plotting with default value --- logger/plotter.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/logger/plotter.py b/logger/plotter.py index a7c0ce1..a3dd90d 100644 --- a/logger/plotter.py +++ b/logger/plotter.py @@ -60,6 +60,8 @@ def _plot_xy(self, name, tag, x, y, time_idx=True): Creates a window if it does not exist yet. Returns True if data has been sent successfully, False otherwise. """ + tag = None if tag == 'default' else tag + if name not in list(self.windows.keys()): opts = self.windows_opts[name] if 'xlabel' in opts: @@ -69,7 +71,7 @@ def _plot_xy(self, name, tag, x, y, time_idx=True): else: opts['xlabel'] = 'Time (s)' if time_idx else 'Index' - if 'legend' not in opts and tag != 'default': + if 'legend' not in opts and tag: opts['legend'] = [tag] if 'title' not in opts: opts['title'] = name From 0730a253a22eb791e942256ad4bafa9b360c6706 Mon Sep 17 00:00:00 2001 From: lberrada Date: Sat, 10 Feb 2018 12:05:52 +0000 Subject: [PATCH 5/5] set visdom windows opts only once --- logger/xp.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/logger/xp.py b/logger/xp.py index 98b2eb1..a1cf6ab 100644 --- a/logger/xp.py +++ b/logger/xp.py @@ -228,7 +228,8 @@ def to_visdom(self, visdom_opts=None, xlabel=None): self.plotter = Plotter(self, visdom_opts, xlabel) # restore visdom options that have been saved (if experiment loaded from file) if hasattr(self, 'visdom_win_opts'): - for (name, opts) in self.visdom_win_opts.items(): + windows_opts = self.__dict__.pop('visdom_win_opts') + for (name, opts) in windows_opts.items(): self.plotter.set_win_opts(name, opts) self.plotter.plot_xp(self)