예제 #1
0
def show_keypoints(chip, kpts, fnum=0, pnum=None, **kwargs):
    r"""
    Args:
        chip (ndarray[uint8_t, ndim=2]):  annotation image data
        kpts (ndarray[float32_t, ndim=2]):  keypoints
        fnum (int):  figure number(default = 0)
        pnum (tuple):  plot number(default = None)

    Kwargs:
        ddd, title, figtitle, interpolation, cmap, heatmap, data_colorbar,
        darken, update, redraw_image, docla, doclf, projection, sel_fx

    CommandLine:
        python -m plottool.viz_keypoints --exec-show_keypoints

    Example:
        >>> # DISABLE_DOCTEST
        >>> from plottool.viz_keypoints import *  # NOQA
        >>> import vtool as vt
        >>> kpts, vecs, chip = testdata_kpts()
        >>> fnum = 0
        >>> pnum = None
        >>> result = show_keypoints(chip, kpts, fnum, pnum)
        >>> print(result)
    """
    #printDBG('[df2.show_kpts] %r' % (kwargs.keys(),))
    fig, ax = df2.imshow(chip, fnum=fnum, pnum=pnum, **kwargs)
    _annotate_kpts(kpts, **kwargs)
    ph.set_plotdat(ax, 'viztype', 'keypoints')
    ph.set_plotdat(ax, 'kpts', kpts)
    if kwargs.get('ddd', False):
        ph.draw()
예제 #2
0
파일: viz_chip.py 프로젝트: byteyoo/ibeis
def show_chip(ibs, aid, in_image=False, annote=True, **kwargs):
    """ Driver function to show chips """
    printDBG('[viz] show_chip()')
    vh.ibsfuncs.assert_valid_aids(ibs, (aid,))
    #utool.embed()
    # Get chip
    chip = vh.get_chips(ibs, aid, in_image, **kwargs)
    # Create chip title
    chip_text = vh.get_annot_texts(ibs, [aid], **kwargs)[0]
    # Draw chip
    fig, ax = df2.imshow(chip, **kwargs)
    # Populate axis user data
    vh.set_ibsdat(ax, 'viztype', 'chip')
    vh.set_ibsdat(ax, 'aid', aid)
    if annote and not kwargs.get('nokpts', False):
        # Get and draw keypoints
        kpts = vh.get_kpts(ibs, aid, in_image, **kwargs)
        _annotate_kpts(kpts, **kwargs)
    df2.upperleft_text(chip_text, color=kwargs.get('text_color', None))
    if not kwargs.get('notitle', False):
        ax.set_title(chip_text)
    if in_image:
        gid = ibs.get_annot_gids(aid)
        aid_list = ibs.get_image_aids(gid)
        annotekw = viz_image.get_annot_annotations(ibs, aid_list, sel_aids=[aid])
        viz_image2.draw_image_overlay(ax, **annotekw)
예제 #3
0
 def _draw_chip(px, title, chip, inliers, kpts1_m, kpts2_m, H1=None):
     if isinstance(px, tuple):
         pnum = px
         df2.imshow(chip, title=title, fnum=fnum, pnum=pnum)
         px = pnum[2]
     else:
         df2.imshow(chip, title=title, fnum=fnum, pnum=pnum2_(px))
     if kpts1_m is not None:
         _draw_kpts(kpts1_m, color=color1_dark, H=H1, **out_kwargs)
         draw_inlier_kpts(kpts1_m, inliers, color1, H=H1)
     if kpts2_m is not None:
         _draw_kpts(kpts2_m, color=color2_dark, **out_kwargs)
         draw_inlier_kpts(kpts2_m, inliers, color2)
     if kpts2_m is not None and kpts1_m is not None and show_lines:
         __fm = np.vstack((inliers, inliers)).T
         df2.draw_lines2(kpts1_m, kpts2_m, __fm,
                         color_list=[custom_constants.ORANGE], lw=2,
                         line_alpha=1,
                         H1=H1)
     return px + 1
예제 #4
0
def show_image(img, bbox_list=[],  title='', theta_list=None,
               text_list=None, sel_list=None, draw_lbls=True,
               fnum=None, annote=True, **kwargs):
    """ Driver function to show images """
    # Shows an image with annotations
    if fnum is None:
        fnum = df2.next_fnum()
    fig, ax = df2.imshow(img, title=title, fnum=fnum, docla=True, **kwargs)
    df2.remove_patches(ax)
    if annote:
        draw_image_overlay(ax, bbox_list, theta_list, text_list, sel_list,
                           draw_lbls)
    return fig, ax
예제 #5
0
 def _draw_chip(px, title, chip, inliers, kpts1_m, kpts2_m, H1=None):
     if isinstance(px, tuple):
         pnum = px
         df2.imshow(chip, title=title, fnum=fnum, pnum=pnum)
         px = pnum[2]
     else:
         df2.imshow(chip, title=title, fnum=fnum, pnum=pnum2_(px))
     if kpts1_m is not None:
         _draw_kpts(kpts1_m, color=color1_dark, H=H1, **out_kwargs)
         draw_inlier_kpts(kpts1_m, inliers, color1, H=H1)
     if kpts2_m is not None:
         _draw_kpts(kpts2_m, color=color2_dark, **out_kwargs)
         draw_inlier_kpts(kpts2_m, inliers, color2)
     if kpts2_m is not None and kpts1_m is not None and show_lines:
         __fm = np.vstack((inliers, inliers)).T
         df2.draw_lines2(kpts1_m,
                         kpts2_m,
                         __fm,
                         color_list=[custom_constants.ORANGE],
                         lw=2,
                         line_alpha=1,
                         H1=H1)
     return px + 1
예제 #6
0
파일: viz_allres.py 프로젝트: byteyoo/ibeis
def plot_score_matrix(allres):
    print('[viz] plotting score matrix')
    score_matrix = allres.score_matrix
    title = 'Score Matrix\n' + allres.title_suffix
    # Find inliers
    #inliers = util.find_std_inliers(score_matrix)
    #max_inlier = score_matrix[inliers].max()
    # Trunate above 255
    score_img = np.copy(score_matrix)
    #score_img[score_img < 0] = 0
    #score_img[score_img > 255] = 255
    #dim = 0
    #score_img = util.norm_zero_one(score_img, dim=dim)
    # Make colors
    scores = score_img.flatten()
    colors = df2.scores_to_color(scores, logscale=True)
    cmap = df2.scores_to_cmap(scores, colors)
    df2.figure(fnum=FIGNUM, doclf=True, title=title)
    # Show score matrix
    df2.imshow(score_img, fnum=FIGNUM, cmap=cmap)
    # Colorbar
    df2.colorbar(scores, colors)
    df2.set_xlabel('database')
    df2.set_ylabel('queries')
예제 #7
0
def plot_score_matrix(allres):
    print('[viz] plotting score matrix')
    score_matrix = allres.score_matrix
    title = 'Score Matrix\n' + allres.title_suffix
    # Find inliers
    #inliers = util.find_std_inliers(score_matrix)
    #max_inlier = score_matrix[inliers].max()
    # Trunate above 255
    score_img = np.copy(score_matrix)
    #score_img[score_img < 0] = 0
    #score_img[score_img > 255] = 255
    #dim = 0
    #score_img = util.norm_zero_one(score_img, dim=dim)
    # Make colors
    scores = score_img.flatten()
    colors = df2.scores_to_color(scores, logscale=True)
    cmap = df2.scores_to_cmap(scores, colors)
    df2.figure(fnum=FIGNUM, doclf=True, title=title)
    # Show score matrix
    df2.imshow(score_img, fnum=FIGNUM, cmap=cmap)
    # Colorbar
    df2.colorbar(scores, colors)
    df2.set_xlabel('database')
    df2.set_ylabel('queries')
예제 #8
0
def show_image(img,
               bbox_list=[],
               title='',
               theta_list=None,
               text_list=None,
               sel_list=None,
               draw_lbls=True,
               fnum=None,
               annote=True,
               **kwargs):
    """ Driver function to show images """
    # Shows an image with annotations
    if fnum is None:
        fnum = df2.next_fnum()
    fig, ax = df2.imshow(img, title=title, fnum=fnum, docla=True, **kwargs)
    df2.remove_patches(ax)
    if annote:
        draw_image_overlay(ax, bbox_list, theta_list, text_list, sel_list,
                           draw_lbls)
    return fig, ax
예제 #9
0
def TEST_figure1(wpatch, gradx, grady, gmag, gori, hist, centers):
    from plottool import draw_func2 as df2
    import plottool
    import vtool.patch as ptool
    print('[rotinvar] 4) Draw histogram with interpolation annotations')
    fnum = 1
    gorimag = plottool.color_orimag(gori, gmag, True)
    nRow, nCol = (2, 7)

    df2.figure(fnum=1, pnum=(nRow, 1, nRow), doclf=True, docla=True)
    plottool.draw_hist_subbin_maxima(hist, centers)
    df2.set_xlabel('grad orientation (radians)')
    df2.set_ylabel('grad magnitude')
    df2.set_title('dominant orientations')

    print('[rotinvar] 5) Show patch, gradients, magintude, and orientation')
    df2.imshow(wpatch, pnum=(nRow, nCol, 1), fnum=fnum, title='patch')
    df2.draw_vector_field(gradx,
                          grady,
                          pnum=(nRow, nCol, 2),
                          fnum=fnum,
                          title='gori (vec)')
    df2.imshow(gorimag, pnum=(nRow, nCol, 3), fnum=fnum, title='gori (col)')
    df2.imshow(np.abs(gradx), pnum=(nRow, nCol, 4), fnum=fnum, title='gradx')
    df2.imshow(np.abs(grady), pnum=(nRow, nCol, 5), fnum=fnum, title='grady')
    df2.imshow(gmag, pnum=(nRow, nCol, 6), fnum=fnum, title='gmag')

    gpatch = ptool.gaussian_patch(shape=gori.shape)
    df2.imshow(gpatch * 255,
               pnum=(nRow, nCol, 7),
               fnum=fnum,
               title='gauss weights',
               cmap_='hot')
    #gpatch3 = np.dstack((gpatch, gpatch, gpatch))
    #df2.draw_vector_field(gradx * gpatch, grady * gpatch, pnum=(nRow, nCol, 8), fnum=fnum, title='gori (vec)')
    #df2.imshow(gorimag * gpatch3, pnum=(nRow, nCol, 9), fnum=fnum, title='gori (col)')
    #df2.imshow(gradx * gpatch,   pnum=(nRow, nCol, 10), fnum=fnum, title='gradx')
    #df2.imshow(grady * gpatch,   pnum=(nRow, nCol, 11), fnum=fnum, title='grady')
    #df2.imshow(gmag * gpatch,    pnum=(nRow, nCol, 12), fnum=fnum, title='gmag')
    return locals()
예제 #10
0
def draw_feat_row(
    chip,
    fx,
    kp,
    sift,
    fnum,
    nRows,
    nCols=None,
    px=None,
    prevsift=None,
    origsift=None,
    aid=None,
    info="",
    type_=None,
    shape_labels=False,
    vecfield=False,
    multicolored_arms=False,
    draw_chip=False,
    draw_warped=True,
    draw_unwarped=True,
    draw_desc=True,
    rect=True,
    ori=True,
    pts=False,
    **kwargs
):
    """
    draw_feat_row

    SeeAlso:
        ibeis.viz.viz_nearest_descriptors
        ~/code/ibeis/ibeis/viz/viz_nearest_descriptors.py

    CommandLine:

        # Use this to find the fx you want to visualize
        python -m plottool.interact_keypoints --test-ishow_keypoints --show --fname zebra.png

        # Use this to visualize the featrow
        python -m plottool.viz_featrow --test-draw_feat_row --show
        python -m plottool.viz_featrow --test-draw_feat_row --show --fname zebra.png --fx=121 --feat-all --no-sift
        python -m plottool.viz_featrow --test-draw_feat_row --dpath figures --save ~/latex/crall-candidacy-2015/figures/viz_featrow.jpg

    Example:
        >>> # DISABLE_DOCTEST
        >>> from plottool.viz_featrow import *  # NOQA
        >>> import plottool as pt
        >>> # build test data
        >>> kpts, vecs, imgBGR = pt.viz_keypoints.testdata_kpts()
        >>> chip = imgBGR
        >>> print('There are %d features' % (len(vecs)))
        >>> fx = ut.get_argval('--fx', type_=int, default=0)
        >>> kp = kpts[fx]
        >>> sift = vecs[fx]
        >>> fnum = 1
        >>> nRows = 1
        >>> nCols = 2
        >>> px = 0
        >>> hack = ut.get_argflag('--feat-all')
        >>> sift = sift if not ut.get_argflag('--no-sift') else None
        >>> draw_desc = sift is not None
        >>> kw = dict(
        >>>     prevsift=None, origsift=None, aid=None, info='', type_=None,
        >>>     shape_labels=False, vecfield=False, multicolored_arms=True,
        >>>     draw_chip=hack, draw_unwarped=hack, draw_warped=True, draw_desc=draw_desc
        >>> )
        >>> # execute function
        >>> result = draw_feat_row(chip, fx, kp, sift, fnum, nRows, nCols, px,
        >>>                           rect=False, ori=False, pts=False, **kw)
        >>> # verify results
        >>> print(result)
        >>> pt.show_if_requested()
    """
    import numpy as np
    import vtool as vt

    # should not need ncols here

    if nCols is not None:
        if ut.VERBOSE:
            print("Warning nCols is no longer needed")
    # assert nCols_ == nCols
    nCols = draw_chip + draw_unwarped + draw_warped + draw_desc

    pnum_ = df2.make_pnum_nextgen(nRows, nCols, start=px)

    # pnum_ = df2.get_pnum_func(nRows, nCols, base=1)
    # countgen = itertools.count(1)

    # pnumgen_ = df2.make_pnum_nextgen(nRows, nCols, base=1)

    def _draw_patch(**kwargs):
        return df2.draw_keypoint_patch(
            chip,
            kp,
            sift,
            rect=rect,
            ori=ori,
            pts=pts,
            ori_color=custom_constants.DEEP_PINK,
            multicolored_arms=multicolored_arms,
            **kwargs
        )

    # Feature strings
    xy_str, shape_str, scale, ori_str = ph.kp_info(kp)

    if draw_chip:
        pnum = pnum_()
        df2.imshow(chip, fnum=fnum, pnum=pnum)
        kpts_kw = dict(ell_linewidth=5, ell_alpha=1.0)
        kpts_kw.update(kwargs)
        df2.draw_kpts2([kp], **kpts_kw)

    if draw_unwarped:
        # Draw the unwarped selected feature
        # ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)))
        # pnum = pnum_(px + six.next(countgen)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum)
        ph.set_plotdat(ax, "viztype", "unwarped")
        ph.set_plotdat(ax, "aid", aid)
        ph.set_plotdat(ax, "fx", fx)
        if shape_labels:
            unwarped_lbl = "affine feature invV =\n" + shape_str + "\n" + ori_str
            custom_figure.set_xlabel(unwarped_lbl, ax)

    if draw_warped:
        # Draw the warped selected feature
        # ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)), warped=True)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum, warped=True, **kwargs)
        ph.set_plotdat(ax, "viztype", "warped")
        ph.set_plotdat(ax, "aid", aid)
        ph.set_plotdat(ax, "fx", fx)
        if shape_labels:
            warped_lbl = ("warped feature\n" + "fx=%r scale=%.1f\n" + "%s") % (fx, scale, xy_str)
        else:
            warped_lbl = ""
        warped_lbl += info
        custom_figure.set_xlabel(warped_lbl, ax)

    if draw_desc:
        border_color = {
            "None": None,
            "query": None,
            "match": custom_constants.BLUE,
            "norm": custom_constants.ORANGE,
        }.get(str(type_).lower(), None)
        if border_color is not None:
            df2.draw_border(ax, color=border_color)

        # Draw the SIFT representation
        # pnum = pnum_(px + six.next(countgen))
        pnum = pnum_()
        sift_as_vecfield = ph.SIFT_OR_VECFIELD or vecfield
        if sift_as_vecfield:
            custom_figure.figure(fnum=fnum, pnum=pnum)
            df2.draw_keypoint_gradient_orientations(chip, kp, sift=sift)
        else:
            if sift.dtype.type == np.uint8:
                sigtitle = "sift histogram" if (px % 3) == 0 else ""
                ax = df2.plot_sift_signature(sift, sigtitle, fnum=fnum, pnum=pnum)
            else:
                sigtitle = "descriptor vector" if (px % 3) == 0 else ""
                ax = df2.plot_descriptor_signature(sift, sigtitle, fnum=fnum, pnum=pnum)
            ax._hs_viztype = "histogram"
        # dist_list = ['L1', 'L2', 'hist_isect', 'emd']
        # dist_list = ['L2', 'hist_isect']
        # dist_list = ['L2']
        # dist_list = ['bar_L2_sift', 'cos_sift']
        # dist_list = ['L2_sift', 'bar_cos_sift']
        dist_list = ["L2_sift"]
        dist_str_list = []
        if origsift is not None:
            distmap_orig = vt.compute_distances(sift, origsift, dist_list)
            dist_str_list.append(
                "query_dist: "
                + ", ".join(["(%s, %s)" % (key, formatdist(val)) for key, val in six.iteritems(distmap_orig)])
            )
        if prevsift is not None:
            distmap_prev = vt.compute_distances(sift, prevsift, dist_list)
            dist_str_list.append(
                "prev_dist: "
                + ", ".join(["(%s, %s)" % (key, formatdist(val)) for key, val in six.iteritems(distmap_prev)])
            )
        dist_str = "\n".join(dist_str_list)
        custom_figure.set_xlabel(dist_str)
    return px + nCols
예제 #11
0
def draw_feat_row(chip,
                  fx,
                  kp,
                  sift,
                  fnum,
                  nRows,
                  nCols=None,
                  px=None,
                  prevsift=None,
                  origsift=None,
                  aid=None,
                  info='',
                  type_=None,
                  shape_labels=False,
                  vecfield=False,
                  multicolored_arms=False,
                  draw_chip=False,
                  draw_warped=True,
                  draw_unwarped=True,
                  draw_desc=True,
                  rect=True,
                  ori=True,
                  pts=False,
                  **kwargs):
    """
    draw_feat_row

    SeeAlso:
        ibeis.viz.viz_nearest_descriptors
        ~/code/ibeis/ibeis/viz/viz_nearest_descriptors.py

    CommandLine:

        # Use this to find the fx you want to visualize
        python -m plottool.interact_keypoints --test-ishow_keypoints --show --fname zebra.png

        # Use this to visualize the featrow
        python -m plottool.viz_featrow --test-draw_feat_row --show
        python -m plottool.viz_featrow --test-draw_feat_row --show --fname zebra.png --fx=121 --feat-all --no-sift
        python -m plottool.viz_featrow --test-draw_feat_row --dpath figures --save ~/latex/crall-candidacy-2015/figures/viz_featrow.jpg

    Example:
        >>> # DISABLE_DOCTEST
        >>> from plottool.viz_featrow import *  # NOQA
        >>> import plottool as pt
        >>> # build test data
        >>> kpts, vecs, imgBGR = pt.viz_keypoints.testdata_kpts()
        >>> chip = imgBGR
        >>> print('There are %d features' % (len(vecs)))
        >>> fx = ut.get_argval('--fx', type_=int, default=0)
        >>> kp = kpts[fx]
        >>> sift = vecs[fx]
        >>> fnum = 1
        >>> nRows = 1
        >>> nCols = 2
        >>> px = 0
        >>> hack = ut.get_argflag('--feat-all')
        >>> sift = sift if not ut.get_argflag('--no-sift') else None
        >>> draw_desc = sift is not None
        >>> kw = dict(
        >>>     prevsift=None, origsift=None, aid=None, info='', type_=None,
        >>>     shape_labels=False, vecfield=False, multicolored_arms=True,
        >>>     draw_chip=hack, draw_unwarped=hack, draw_warped=True, draw_desc=draw_desc
        >>> )
        >>> # execute function
        >>> result = draw_feat_row(chip, fx, kp, sift, fnum, nRows, nCols, px,
        >>>                           rect=False, ori=False, pts=False, **kw)
        >>> # verify results
        >>> print(result)
        >>> pt.show_if_requested()
    """
    import numpy as np
    import vtool as vt
    # should not need ncols here

    if nCols is not None:
        if ut.VERBOSE:
            print('Warning nCols is no longer needed')
    #assert nCols_ == nCols
    nCols = (draw_chip + draw_unwarped + draw_warped + draw_desc)

    pnum_ = df2.make_pnum_nextgen(nRows, nCols, start=px)

    #pnum_ = df2.get_pnum_func(nRows, nCols, base=1)
    #countgen = itertools.count(1)

    #pnumgen_ = df2.make_pnum_nextgen(nRows, nCols, base=1)

    def _draw_patch(**kwargs):
        return df2.draw_keypoint_patch(chip,
                                       kp,
                                       sift,
                                       rect=rect,
                                       ori=ori,
                                       pts=pts,
                                       ori_color=custom_constants.DEEP_PINK,
                                       multicolored_arms=multicolored_arms,
                                       **kwargs)

    # Feature strings
    xy_str, shape_str, scale, ori_str = ph.kp_info(kp)

    if draw_chip:
        pnum = pnum_()
        df2.imshow(chip, fnum=fnum, pnum=pnum)
        kpts_kw = dict(ell_linewidth=5, ell_alpha=1.0)
        kpts_kw.update(kwargs)
        df2.draw_kpts2([kp], **kpts_kw)

    if draw_unwarped:
        # Draw the unwarped selected feature
        #ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)))
        #pnum = pnum_(px + six.next(countgen)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum)
        ph.set_plotdat(ax, 'viztype', 'unwarped')
        ph.set_plotdat(ax, 'aid', aid)
        ph.set_plotdat(ax, 'fx', fx)
        if shape_labels:
            unwarped_lbl = 'affine feature invV =\n' + shape_str + '\n' + ori_str
            custom_figure.set_xlabel(unwarped_lbl, ax)

    if draw_warped:
        # Draw the warped selected feature
        #ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)), warped=True)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum, warped=True, **kwargs)
        ph.set_plotdat(ax, 'viztype', 'warped')
        ph.set_plotdat(ax, 'aid', aid)
        ph.set_plotdat(ax, 'fx', fx)
        if shape_labels:
            warped_lbl = ('warped feature\n' + 'fx=%r scale=%.1f\n' +
                          '%s') % (fx, scale, xy_str)
        else:
            warped_lbl = ''
        warped_lbl += info
        custom_figure.set_xlabel(warped_lbl, ax)

    if draw_desc:
        border_color = {
            'None': None,
            'query': None,
            'match': custom_constants.BLUE,
            'norm': custom_constants.ORANGE
        }.get(str(type_).lower(), None)
        if border_color is not None:
            df2.draw_border(ax, color=border_color)

        # Draw the SIFT representation
        #pnum = pnum_(px + six.next(countgen))
        pnum = pnum_()
        sift_as_vecfield = ph.SIFT_OR_VECFIELD or vecfield
        if sift_as_vecfield:
            custom_figure.figure(fnum=fnum, pnum=pnum)
            df2.draw_keypoint_gradient_orientations(chip, kp, sift=sift)
        else:
            if sift.dtype.type == np.uint8:
                sigtitle = 'sift histogram' if (px % 3) == 0 else ''
                ax = df2.plot_sift_signature(sift,
                                             sigtitle,
                                             fnum=fnum,
                                             pnum=pnum)
            else:
                sigtitle = 'descriptor vector' if (px % 3) == 0 else ''
                ax = df2.plot_descriptor_signature(sift,
                                                   sigtitle,
                                                   fnum=fnum,
                                                   pnum=pnum)
            ax._hs_viztype = 'histogram'
        #dist_list = ['L1', 'L2', 'hist_isect', 'emd']
        #dist_list = ['L2', 'hist_isect']
        #dist_list = ['L2']
        #dist_list = ['bar_L2_sift', 'cos_sift']
        #dist_list = ['L2_sift', 'bar_cos_sift']
        dist_list = ['L2_sift']
        dist_str_list = []
        if origsift is not None:
            distmap_orig = vt.compute_distances(sift, origsift, dist_list)
            dist_str_list.append('query_dist: ' + ', '.join([
                '(%s, %s)' % (key, formatdist(val))
                for key, val in six.iteritems(distmap_orig)
            ]))
        if prevsift is not None:
            distmap_prev = vt.compute_distances(sift, prevsift, dist_list)
            dist_str_list.append('prev_dist: ' + ', '.join([
                '(%s, %s)' % (key, formatdist(val))
                for key, val in six.iteritems(distmap_prev)
            ]))
        dist_str = '\n'.join(dist_str_list)
        custom_figure.set_xlabel(dist_str)
    return px + nCols