def _report_timing(self, timing_info):
    idx_patt = re.compile(('%s_(\\d+)_(\\d+)' % self.basename))
    job_segs = NestedDict()
    plot_set = set()
    for (stage, stage_d) in timing_info.items():
        for (metric, metric_d) in stage_d.items():
            for (job_name, t) in metric_d.items():
                job_segs[job_name][stage][metric] = t
                m = idx_patt.match(job_name)
                if (m is None):
                    logger.error(('Unexpectedly formatted name: %s.' % job_name))
                    continue
                key = tuple(([int(n) for n in m.groups()] + [job_name]))
                plot_set.add(key)
    plot_list = list(plot_set)
    plot_list.sort()
    all_times = [dt for job in job_segs.values() for stage in job.values() for (metric, dt) in stage.items() if (metric != 'duration')]
    all_start = min(all_times)
    all_end = max(all_times)

    def get_time_tuple(stage_data):
        start_seconds = (stage_data['start'] - all_start).total_seconds()
        return (start_seconds, stage_data['duration'].total_seconds())
    w = 6.5
    h = 9
    fig = plt.figure(figsize=(w, h))
    gs = plt.GridSpec(2, 1, height_ratios=[10, 1])
    ax0 = plt.subplot(gs[0])
    ytick_pairs = []
    stages = ['reading', 'statement production', 'stats']
    t = arange((all_end - all_start).total_seconds())
    counts = dict.fromkeys((['jobs'] + stages))
    for k in counts.keys():
        counts[k] = array([0 for _ in t])
    for (i, job_tpl) in enumerate(plot_list):
        (s_ix, e_ix, job_name) = job_tpl
        job_d = job_segs[job_name]
        xs = [get_time_tuple(job_d[stg]) for stg in stages]
        ys = (s_ix, ((e_ix - s_ix) * 0.9))
        ytick_pairs.append((((s_ix + e_ix) / 2), ('%s_%s' % (s_ix, e_ix))))
        logger.debug(('Making plot for: %s' % str((job_name, xs, ys))))
        ax0.broken_barh(xs, ys, facecolors=('red', 'green', 'blue'))
        for (n, stg) in enumerate(stages):
            cs = counts[stg]
            start = xs[n][0]
            dur = xs[n][1]
            cs[((t > start) & (t < (start + dur)))] += 1
        cs = counts['jobs']
        cs[((t > xs[0][0]) & (t < (xs[(- 1)][0] + xs[(- 1)][1])))] += 1
    ax0.tick_params(top='off', left='off', right='off', bottom='off', labelleft='on', labelbottom='off')
    for spine in ax0.spines.values():
        spine.set_visible(False)
    total_time = (all_end - all_start).total_seconds()
    ax0.set_xlim(0, total_time)
    ax0.set_ylabel((self.basename + '_ ...'))
    print(ytick_pairs)
    (yticks, ylabels) = zip(*ytick_pairs)
    print(yticks)
    if (not self.ids_per_job):
        print([(yticks[(i + 1)] - yticks[i]) for i in range((len(yticks) - 1))])
        spacing = median([(yticks[(i + 1)] - yticks[i]) for i in range((len(yticks) - 1))])
        spacing = max(1, spacing)
    else:
        spacing = self.ids_per_job
    print(spacing)
    print(yticks[0], yticks[(- 1)])
    ytick_range = list(arange(yticks[0], (yticks[(- 1)] + spacing), spacing))
    ylabel_filled = []
    for ytick in ytick_range:
        if (ytick in yticks):
            ylabel_filled.append(ylabels[yticks.index(ytick)])
        else:
            ylabel_filled.append('FAILED')
    ax0.set_ylim(0, (max(ytick_range) + spacing))
    ax0.set_yticks(ytick_range)
    ax0.set_yticklabels(ylabel_filled)
    legend_list = []
    color_map = {'jobs': 'k', 'reading': 'r', 'statement production': 'g', 'stats': 'b'}
    ax1 = plt.subplot(gs[1], sharex=ax0)
    for (k, cs) in counts.items():
        legend_list.append(k)
        ax1.plot(t, cs, color=color_map[k])
    for (lbl, spine) in ax1.spines.items():
        spine.set_visible(False)
    max_n = max(counts['jobs'])
    ax1.set_ylim(0, (max_n + 1))
    ax1.set_xlim(0, total_time)
    yticks = list(range(0, (max_n - (max_n // 5)), max(1, (max_n // 5))))
    ax1.set_yticks((yticks + [max_n]))
    ax1.set_yticklabels(([str(n) for n in yticks] + [('max=%d' % max_n)]))
    ax1.set_ylabel('N_jobs')
    ax1.set_xlabel('Time since beginning [seconds]')
    fig.tight_layout()
    img_path = 'time_figure.png'
    fig.savefig(img_path)
    self.reporter.add_image(img_path, width=w, height=h, section='Plots')
    return
def _report_timing(self, timing_info):
    idx_patt = re.compile(('%s_(\\d+)_(\\d+)' % self.basename))
    job_segs = NestedDict()
    plot_set = set()
    for (stage, stage_d) in timing_info.items():
        for (metric, metric_d) in stage_d.items():
            for (job_name, t) in metric_d.items():
                job_segs[job_name][stage][metric] = t
                m = idx_patt.match(job_name)
                if (m is None):
                    logger.error(('Unexpectedly formatted name: %s.' % job_name))
                    continue
                key = tuple(([int(n) for n in m.groups()] + [job_name]))
                plot_set.add(key)
    plot_list = list(plot_set)
    plot_list.sort()
    all_times = [dt for job in job_segs.values() for stage in job.values() for (metric, dt) in stage.items() if (metric != 'duration')]
    all_start = min(all_times)
    all_end = max(all_times)

    def get_time_tuple(stage_data):
        start_seconds = (stage_data['start'] - all_start).total_seconds()
        return (start_seconds, stage_data['duration'].total_seconds())
    w = 6.5
    h = 9
    fig = plt.figure(figsize=(w, h))
    gs = plt.GridSpec(2, 1, height_ratios=[10, 1])
    ax0 = plt.subplot(gs[0])
    ytick_pairs = []
    stages = ['reading', 'statement production', 'stats']
    t = arange((all_end - all_start).total_seconds())
    counts = dict.fromkeys((['jobs'] + stages))
    for k in counts.keys():
        counts[k] = array([0 for _ in t])
    for (i, job_tpl) in enumerate(plot_list):
        (s_ix, e_ix, job_name) = job_tpl
        job_d = job_segs[job_name]
        xs = [get_time_tuple(job_d[stg]) for stg in stages]
        ys = (s_ix, ((e_ix - s_ix) * 0.9))
        ytick_pairs.append((((s_ix + e_ix) / 2), ('%s_%s' % (s_ix, e_ix))))
        logger.debug(('Making plot for: %s' % str((job_name, xs, ys))))
        ax0.broken_barh(xs, ys, facecolors=('red', 'green', 'blue'))
        for (n, stg) in enumerate(stages):
            cs = counts[stg]
            start = xs[n][0]
            dur = xs[n][1]
            cs[((t > start) & (t < (start + dur)))] += 1
        cs = counts['jobs']
        cs[((t > xs[0][0]) & (t < (xs[(- 1)][0] + xs[(- 1)][1])))] += 1
    ax0.tick_params(top='off', left='off', right='off', bottom='off', labelleft='on', labelbottom='off')
    for spine in ax0.spines.values():
        spine.set_visible(False)
    total_time = (all_end - all_start).total_seconds()
    ax0.set_xlim(0, total_time)
    ax0.set_ylabel((self.basename + '_ ...'))
    print(ytick_pairs)
    (yticks, ylabels) = zip(*ytick_pairs)
    print(yticks)
    if (not self.ids_per_job):
        print([(yticks[(i + 1)] - yticks[i]) for i in range((len(yticks) - 1))])
        spacing = median([(yticks[(i + 1)] - yticks[i]) for i in range((len(yticks) - 1))])
        spacing = max(1, spacing)
    else:
        spacing = self.ids_per_job
    print(spacing)
    print(yticks[0], yticks[(- 1)])
    ytick_range = list(arange(yticks[0], (yticks[(- 1)] + spacing), spacing))
    ylabel_filled = []
    for ytick in ytick_range:
        if (ytick in yticks):
            ylabel_filled.append(ylabels[yticks.index(ytick)])
        else:
            ylabel_filled.append('FAILED')
    ax0.set_ylim(0, (max(ytick_range) + spacing))
    ax0.set_yticks(ytick_range)
    ax0.set_yticklabels(ylabel_filled)
    legend_list = []
    color_map = {'jobs': 'k', 'reading': 'r', 'statement production': 'g', 'stats': 'b'}
    ax1 = plt.subplot(gs[1], sharex=ax0)
    for (k, cs) in counts.items():
        legend_list.append(k)
        ax1.plot(t, cs, color=color_map[k])
    for (lbl, spine) in ax1.spines.items():
        spine.set_visible(False)
    max_n = max(counts['jobs'])
    ax1.set_ylim(0, (max_n + 1))
    ax1.set_xlim(0, total_time)
    yticks = list(range(0, (max_n - (max_n // 5)), max(1, (max_n // 5))))
    ax1.set_yticks((yticks + [max_n]))
    ax1.set_yticklabels(([str(n) for n in yticks] + [('max=%d' % max_n)]))
    ax1.set_ylabel('N_jobs')
    ax1.set_xlabel('Time since beginning [seconds]')
    fig.tight_layout()
    img_path = 'time_figure.png'
    fig.savefig(img_path)
    self.reporter.add_image(img_path, width=w, height=h, section='Plots')
    return