def on_click_inside(self, event, ax):
        import wbia.plottool as pt

        viztype = ph.get_plotdat(ax, 'viztype', None)
        logger.info('[ik] viztype=%r' % viztype)
        if viztype is None:
            pass
        elif viztype == 'keypoints':
            kpts = ph.get_plotdat(ax, 'kpts', [])
            if len(kpts) == 0:
                logger.info('...nokpts')
            else:
                logger.info('...nearest')
                x, y = event.xdata, event.ydata
                import vtool as vt

                fx = vt.nearest_point(x, y, kpts)[0]
                self._select_ith_kpt(fx)
        elif viztype == 'warped':
            hs_fx = ph.get_plotdat(ax, 'fx', None)
            if hs_fx is not None:
                kp = self.kpts[hs_fx]  # FIXME
                sift = self.vecs[hs_fx]
                df2.draw_keypoint_gradient_orientations(self.chip,
                                                        kp,
                                                        sift=sift,
                                                        mode='vec',
                                                        fnum=pt.next_fnum())
                pt.draw()
        elif viztype.startswith('colorbar'):
            pass
        else:
            logger.info('...unhandled')
        self.draw()
    def on_click_inside(self, event, ax):
        ax = event.inaxes
        viztype = ph.get_plotdat(ax, 'viztype', '')
        # if verbose:
        #    logger.info(str(event.__dict__))
        logger.info('viztype=%r' % viztype)
        # Clicked a specific matches
        logger.info('plodat_dict = ' + ut.repr2(ph.get_plotdat_dict(ax)))
        if viztype.startswith('chip'):
            from wbia.viz.interact import interact_chip

            options = interact_chip.build_annot_context_options(
                self.ibs,
                self.cm.qaid,
                refresh_func=self._analysis_view,
                with_interact_chip=False,
            )
            self.show_popup_menu(options, event)

        if viztype.startswith(
                'matches') or viztype == 'multi_match':  # why startswith?
            aid2 = ph.get_plotdat(ax, 'aid2', None)
            aid_list = ph.get_plotdat(ax, 'aid_list', None)
            if event.button == 3:  # right-click
                # TODO; this functionality should be in viz.interact
                from wbia.gui import inspect_gui

                logger.info('right click')
                logger.info('qreq_ = %r' % (self.qreq_, ))
                options = inspect_gui.get_aidpair_context_menu_options(
                    self.ibs,
                    self.cm.qaid,
                    aid2,
                    self.cm,
                    qreq_=self.qreq_,
                    update_callback=self.show_page,
                    backend_callback=None,
                    aid_list=aid_list,
                )
                self.show_popup_menu(options, event)
            else:
                # Ctrl-Click
                key = '' if event.key is None else event.key
                logger.info('key = %r' % key)
                if key.find('control') == 0:
                    logger.info('[viz] result control clicked')
                    self.show_sver_process_to_aid(aid2)
                # Left-Click
                else:
                    logger.info('[viz] result clicked')
                    self.show_matches_to_aid(aid2)
        self.draw()
    def _on_keypoints_click(event):
        logger.info('[viz] clicked keypoint view')
        if event is None or event.xdata is None or event.inaxes is None:
            annote_ptr[0] = (annote_ptr[0] + 1) % 3
            mode = annote_ptr[0]
            ell = mode == 1
            pts = mode == 2
            logger.info('... default kpts view mode=%r' % mode)
            _viz_keypoints(fnum, ell=ell, pts=pts,
                           **kwargs)  # MAYBE: remove kwargs
        else:
            ax = event.inaxes
            viztype = ph.get_plotdat(ax, 'viztype', None)
            logger.info('[ik] viztype=%r' % viztype)
            if viztype == 'keypoints':
                kpts = ph.get_plotdat(ax, 'kpts', [])
                if len(kpts) == 0:
                    logger.info('...nokpts')
                else:
                    logger.info('...nearest')
                    x, y = event.xdata, event.ydata
                    import vtool as vt

                    fx = vt.nearest_point(x, y, kpts)[0]
                    _select_ith_kpt(fx)
            elif viztype == 'warped':
                hs_fx = ph.get_plotdat(ax, 'fx', None)
                # kpts = ph.get_plotdat(ax, 'kpts', [])
                if hs_fx is not None:
                    # Ugly. Interactions should be changed to classes.
                    kp = self.kpts[hs_fx]  # FIXME
                    sift = self.vecs[hs_fx]
                    df2.draw_keypoint_gradient_orientations(
                        chip, kp, sift=sift, mode='vec', fnum=df2.next_fnum())
            elif viztype.startswith('colorbar'):
                pass
                # Hack to get a specific scoring feature
                # sortx = self.fs.argsort()
                # idx = np.clip(int(np.round(y * len(sortx))), 0, len(sortx) - 1)
                # mx = sortx[idx]
                # (fx1, fx2) = self.fm[mx]
                # (fx1, fx2) = self.fm[mx]
                # logger.info('... selected score at rank idx=%r' % (idx,))
                # logger.info('... selected score with fs=%r' % (self.fs[mx],))
                # logger.info('... resolved to mx=%r' % mx)
                # logger.info('... fx1, fx2 = %r, %r' % (fx1, fx2,))
                # self.select_ith_match(mx)
            else:
                logger.info('...unhandled')
        ph.draw()
Exemple #4
0
    def on_click_inside(self, event, ax):
        from wbia.plottool import plot_helpers as ph

        (x, y) = (event.xdata, event.ydata)
        viztype = ph.get_plotdat(ax, 'viztype', '')

        if event.button == 3:
            self.show_popup_menu(self.get_popup_options(), event)
            return
        # key = '' if event.key is None else event.key
        # ctrl_down = key.find('control') == 0
        if viztype in ['matches', 'multi_match']:
            if len(self.fm) == 0:
                print('[inter] no feature matches to click')
            else:
                # Normal Click
                # Select nearest feature match to the click
                kpts1_m = self.kpts1[self.fm[:, 0]]
                kpts2_m = self.kpts2[self.fm[:, 1]]
                x2, y2, w2, h2 = self.xywh2
                import vtool as vt

                _mx1, _dist1 = vt.nearest_point(x, y, kpts1_m)
                _mx2, _dist2 = vt.nearest_point(x - x2, y - y2, kpts2_m)
                mx = _mx1 if _dist1 < _dist2 else _mx2
                print('... clicked mx=%r' % mx)
                self.select_ith_match(mx)
        # elif viztype in ['warped', 'unwarped']:
        #    pass
        #    #hs_aid = ax.__dict__.get('_hs_aid', None)
        #    #hs_fx = ax.__dict__.get('_hs_fx', None)
        #    #if hs_aid is not None and viztype == 'unwarped':
        #    #    ishow_chip(ibs, hs_aid, fx=hs_fx, fnum=pt.next_fnum())
        #    #elif hs_aid is not None and viztype == 'warped':
        #    #    viz.show_keypoint_gradient_orientations(ibs, hs_aid,
        #    #    hs_fx, fnum=pt.next_fnum())
        # Click in match axes
        # elif viztype == 'matches' and ctrl_down:
        #    # Ctrl-Click
        #    print('.. control click')
        #    return self.sv_view()
        elif viztype.startswith('colorbar'):
            # Hack to get a specific scoring feature
            sortx = self.fs.argsort()
            idx = np.clip(int(np.round(y * len(sortx))), 0, len(sortx) - 1)
            mx = sortx[idx]
            (fx1, fx2) = self.fm[mx]
            (fx1, fx2) = self.fm[mx]
            print('... selected score at rank idx=%r' % (idx, ))
            print('... selected score with fs=%r' % (self.fs[mx], ))
            print('... resolved to mx=%r' % mx)
            print('... fx1, fx2 = %r, %r' % (
                fx1,
                fx2,
            ))
            self.select_ith_match(mx)
        else:
            print('...Unknown viztype: %r' % viztype)
        self.draw()
    def on_click_inside(self, event, ax):
        index = ph.get_plotdat(ax, 'index')
        print('index = %r' % (index,))
        if index is not None:
            if self.MOUSE_BUTTONS[event.button] == 'right':
                if self.context_option_funcs is not None:
                    # if event.button == 3:
                    options = self.context_option_funcs[index]()
                    self.show_popup_menu(options, event)
            elif self.MOUSE_BUTTONS[event.button] == 'left':
                # bbox_list  = ph.get_plotdat(ax, 'bbox_list')
                gpath = self.gpath_list[index]
                if ut.is_funclike(gpath):
                    print('gpath_isfunklike')
                    print('gpath = %r' % (gpath,))
                    import wbia.plottool as pt

                    fnum = pt.next_fnum()
                    gpath(fnum=fnum)
                    df2.update()
                else:
                    bbox_list = self.bboxes_list[index]
                    print('Bbox of figure: %r' % (bbox_list,))
                    theta_list = self.thetas_list[index]
                    print('theta_list = %r' % (theta_list,))
                    # img = mpimg.imread(gpath)
                    if isinstance(gpath, six.string_types):
                        img = vt.imread(gpath)
                    else:
                        img = gpath
                    fnum = df2.next_fnum()
                    mc = interact_annotations.AnnotationInteraction(
                        img,
                        index,
                        self.update_images,
                        bbox_list=bbox_list,
                        theta_list=theta_list,
                        fnum=fnum,
                    )
                    mc.start()
                    self.mc = mc
                    # """wait for accept
                    # have a flag to tell if a bbox has been changed, on the bbox
                    # list that is brought it" on accept: viz_image2.show_image
                    # callback
                    # """
                    df2.update()
            print('Clicked: ax: num=%r' % index)
 def clear_parent_axes(self, ax):
     """ for clearing axes that we appended anything to """
     child_axes = ph.get_plotdat(ax, 'child_axes', [])
     ph.set_plotdat(ax, 'child_axes', [])
     for subax in child_axes:
         to_remove = None
         for tup in self.scope:
             if tup[1] is subax:
                 to_remove = tup
                 break
         if to_remove is not None:
             self.scope.remove(to_remove)
         subax.cla()
         self.fig.delaxes(subax)
     ph.del_plotdat(ax, df2.DF2_DIVIDER_KEY)
     ax.cla()
Exemple #7
0
    def get_popup_options(self):
        from wbia.gui import inspect_gui

        options = []

        ax = pt.gca()  # HACK

        from wbia.plottool import plot_helpers as ph

        viztype = ph.get_plotdat(ax, 'viztype', '')
        is_match_type = viztype in ['matches', 'multi_match']

        if is_match_type:
            options += inspect_gui.get_aidpair_context_menu_options(
                self.ibs,
                self.qaid,
                self.daid,
                self.cm,
                qreq_=self.qreq_,
                # update_callback=self.show_page,
                # backend_callback=None, aid_list=aid_list)
            )

        options += [
            # ('Toggle same_fig', self.toggle_samefig),
            # ('Toggle vert', self.toggle_vert),
            ('query last feature', self.query_last_feature),
            ('show each chip', self.show_each_chip),
            ('show each distinctiveness chip', self.show_each_dstncvs_chip),
            ('show each foreground weight chip', self.show_each_fgweight_chip),
            ('show each probchip', self.show_each_probchip),
            ('show coverage', self.show_coverage),
            # ('show each probchip', self.query_last_feature),
        ]

        # options.append(('name_interaction', self.name_interaction))
        # if self.H1 is not None:
        #    options.append(('Toggle homog', self.toggle_homog))
        if ut.is_developer():
            options.append(('dev_reload', self.dev_reload))
            options.append(('dev_embed', self.dev_embed))
        # options.append(('cancel', lambda: print('cancel')))
        options += super(MatchInteraction, self).get_popup_options()

        return options
Exemple #8
0
    def on_click_inside(self, event, ax):
        from wbia.plottool import plot_helpers as ph

        ibs = self.ibs
        viztype = ph.get_plotdat(ax, 'viztype', '')
        is_match_type = viztype in ['matches', 'multi_match']

        key = '' if event.key is None else event.key
        logger.info('key=%r ' % key)
        ctrl_down = key.find('control') == 0
        # Click in match axes
        if event.button == 3:
            return super(MatchInteraction, self).on_click_inside(event, ax)
        if is_match_type and ctrl_down:
            # Ctrl-Click
            logger.info('.. control click')
            return self.sv_view()
        elif viztype in ['warped', 'unwarped']:
            logger.info('clicked at patch')
            ut.print_dict(ph.get_plotdat_dict(ax))
            hs_aid = {
                'aid1': self.qaid,
                'aid2': self.daid
            }[vh.get_ibsdat(ax, 'aid', None)]
            hs_fx = vh.get_ibsdat(ax, 'fx', None)
            logger.info('hs_fx = %r' % (hs_fx, ))
            logger.info('hs_aid = %r' % (hs_aid, ))
            if hs_aid is not None and viztype == 'unwarped':
                ishow_chip(ibs, hs_aid, fx=hs_fx, fnum=pt.next_fnum())
            elif hs_aid is not None and viztype == 'warped':
                viz.show_keypoint_gradient_orientations(ibs,
                                                        hs_aid,
                                                        hs_fx,
                                                        fnum=pt.next_fnum())
        else:
            return super(MatchInteraction, self).on_click_inside(event, ax)
        self.draw()
Exemple #9
0
def show_multiple_chips(ibs,
                        aid_list,
                        in_image=True,
                        fnum=0,
                        sel_aids=[],
                        subtitle='',
                        annote=False,
                        **kwargs):
    """
    CommandLine:
        python -m wbia.viz.viz_name --test-show_multiple_chips --show --no-inimage
        python -m wbia.viz.viz_name --test-show_multiple_chips --show --db NNP_Master3 --aids=6435,9861,137,6563,9167,12547,9332,12598,13285 --no-inimage --notitle
        python -m wbia.viz.viz_name --test-show_multiple_chips --show --db NNP_Master3 --aids=137,6563,12547,9332,12598,13285 --no-inimage --notitle --adjust=.05
        python -m wbia.viz.viz_name --test-show_multiple_chips --show --db NNP_Master3 --aids=6563,9332,13285,12598 --no-inimage --notitle --adjust=.05 --rc=1,4
        python -m wbia.viz.viz_name --test-show_multiple_chips --show --db PZ_Master0 --aids=1288 --no-inimage --notitle --adjust=.05
        python -m wbia.viz.viz_name --test-show_multiple_chips --show --db PZ_Master0 --aids=4020,4839 --no-inimage --notitle --adjust=.05

        python -m wbia.viz.viz_name --test-show_multiple_chips --db NNP_Master3 --aids=6524,6540,6571,6751 --no-inimage --notitle --adjust=.05 --diskshow

        python -m wbia.viz.viz_name --test-show_multiple_chips --db PZ_MTEST -a default:index=0:4 --show
        --aids=1 --doboth --show --no-inimage

        python -m wbia.viz.viz_name --test-show_multiple_chips --db PZ_MTEST --aids=1 --doboth --show --no-inimage
        python -m wbia.viz.viz_name --test-show_multiple_chips --db PZ_MTEST --aids=1 --doboth --rc=2,1 --show --no-inimage
        python -m wbia.viz.viz_name --test-show_multiple_chips --db PZ_MTEST --aids=1 --doboth --rc=2,1 --show --notitle --trydrawline --no-draw_lbls
        python -m wbia.viz.viz_name --test-show_multiple_chips --db PZ_MTEST --aids=1,2 --doboth  --show --notitle --trydrawline

        python -m wbia.viz.viz_name --test-show_multiple_chips --db PZ_MTEST --aids=1,2,3,4,5 --doboth --rc=2,5 --show --chrlbl --trydrawline --qualtitle --no-figtitle --notitle
        --doboth
        --doboth --show

        python -m wbia.viz.viz_name --test-show_multiple_chips --db NNP_Master3 --aids=15419 --doboth --rc=2,1 --show --notitle --trydrawline --no-draw_lbls

    Example:
        >>> # DISABLE_DOCTEST
        >>> from wbia.viz.viz_name import *  # NOQA
        >>> import wbia
        >>> ibs, aid_list, in_image = testdata_multichips()
        >>> if True:
        >>>     import matplotlib as mpl
        >>>     from wbia.scripts.thesis import TMP_RC
        >>>     mpl.rcParams.update(TMP_RC)
        >>> fnum = 0
        >>> sel_aids = []
        >>> subtitle = ''
        >>> annote = False
        >>> fig = show_multiple_chips(ibs, aid_list, in_image, fnum, sel_aids, subtitle, annote)
        >>> ut.quit_if_noshow()
        >>> fig.canvas.draw()
        >>> ut.show_if_requested()
    """
    fnum = pt.ensure_fnum(fnum)
    nAids = len(aid_list)
    if nAids == 0:
        fig = df2.figure(fnum=fnum, pnum=(1, 1, 1), **kwargs)
        df2.imshow_null(fnum=fnum, **kwargs)
        return fig
    # Trigger computation of all chips in parallel
    ibsfuncs.ensure_annotation_data(ibs,
                                    aid_list,
                                    chips=(not in_image or annote),
                                    feats=annote)

    logger.info('[viz_name] * annot_vuuid=%r' %
                ((ibs.get_annot_visual_uuids(aid_list), )))
    logger.info('[viz_name] * aid_list=%r' % ((aid_list, )))

    DOBOTH = ut.get_argflag('--doboth')

    rc = ut.get_argval('--rc', type_=list, default=None)
    if rc is None:
        nRows, nCols = ph.get_square_row_cols(nAids * (2 if DOBOTH else 1))
    else:
        nRows, nCols = rc
    notitle = ut.get_argflag('--notitle')
    draw_lbls = not ut.get_argflag('--no-draw_lbls')
    show_chip_kw = dict(annote=annote,
                        in_image=in_image,
                        notitle=notitle,
                        draw_lbls=draw_lbls)
    # logger.info('[viz_name] * r=%r, c=%r' % (nRows, nCols))
    # gs2 = gridspec.GridSpec(nRows, nCols)
    pnum_ = df2.get_pnum_func(nRows, nCols)
    fig = df2.figure(fnum=fnum, pnum=pnum_(0), **kwargs)
    fig.clf()
    ax_list1 = []
    for px, aid in enumerate(aid_list):
        logger.info('px = %r' % (px, ))
        _fig, _ax1 = viz_chip.show_chip(ibs,
                                        aid=aid,
                                        pnum=pnum_(px),
                                        **show_chip_kw)
        logger.info('other_aids = %r' % (ibs.get_annot_contact_aids(aid), ))
        ax = df2.gca()
        ax_list1.append(_ax1)
        if aid in sel_aids:
            df2.draw_border(ax, df2.GREEN, 4)
        if ut.get_argflag('--chrlbl') and not DOBOTH:
            ax.set_xlabel('(' + chr(ord('a') - 1 + px) + ')')
        elif ut.get_argflag('--numlbl') and not DOBOTH:
            ax.set_xlabel('(' + str(px + 1) + ')')
        # plot_aid3(ibs, aid)

    # HACK to show in image and not in image
    if DOBOTH:
        # ut.embed()
        # ph.get_plotdat_dict(ax_list1[1])
        # ph.get_plotdat_dict(ax_list2[1])
        ax_list2 = []

        show_chip_kw['in_image'] = not show_chip_kw['in_image']
        start = px + 1
        for px, aid in enumerate(aid_list, start=start):
            _fig, _ax2 = viz_chip.show_chip(ibs,
                                            aid=aid,
                                            pnum=pnum_(px),
                                            **show_chip_kw)
            ax = df2.gca()
            ax_list2.append(_ax2)

            if ut.get_argflag('--chrlbl'):
                ax.set_xlabel('(' + chr(ord('a') - start + px) + ')')
            elif ut.get_argflag('--numlbl'):
                ax.set_xlabel('(' + str(px - start + 1) + ')')

            if ut.get_argflag('--qualtitle'):
                qualtext = ibs.get_annot_quality_texts(aid)
                ax.set_title(qualtext)

            if aid in sel_aids:
                df2.draw_border(ax, df2.GREEN, 4)

        if in_image:
            ax_list1, ax_list2 = ax_list2, ax_list1

        if ut.get_argflag('--trydrawline'):
            # Unfinished
            # ut.embed()
            # Draw lines between corresponding axes
            # References:
            # http://stackoverflow.com/questions/17543359/drawing-lines-between-two-plots-in-matplotlib
            import matplotlib as mpl
            import vtool as vt

            # !!!
            # http://matplotlib.org/users/transforms_tutorial.html

            # invTransFigure_fn1 = fig.transFigure.inverted().transform
            # invTransFigure_fn2 = fig.transFigure.inverted().transform
            # logger.info(ax_list1)
            # logger.info(ax_list2)
            assert len(ax_list1) == len(ax_list2)

            for ax1, ax2 in zip(ax_list1, ax_list2):
                # _ = ax1.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
                # bbox1 = (0, 0, _.width * fig.dpi, _.height * fig.dpi)

                # returns in figure coordinates
                # bbox1 = df2.get_axis_bbox(ax=ax1)
                # if bbox1[-1] < 0:
                #    # Weird bug
                #    bbox1 = bbox1[1]
                logger.info('--')
                logger.info('ax1 = %r' % (ax1, ))
                logger.info('ax2 = %r' % (ax2, ))
                chipshape = ph.get_plotdat(ax1, 'chipshape')
                # _bbox1 = ax1.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
                # bbox1 = (0, 0, _bbox1.width * fig.dpi, _bbox1.height * fig.dpi)
                bbox1 = (0, 0, chipshape[1], chipshape[0])

                aid_ = ph.get_plotdat(ax2, 'aid')
                aid_list_ = ph.get_plotdat(ax2, 'aid_list')
                index = aid_list_.index(aid_)
                annotation_bbox_list = ph.get_plotdat(ax2,
                                                      'annotation_bbox_list')
                bbox2 = annotation_bbox_list[index]

                logger.info('bbox1 = %r' % (bbox1, ))
                logger.info('bbox2 = %r' % (bbox2, ))

                vert_list1 = np.array(vt.verts_from_bbox(bbox1))
                vert_list2 = np.array(vt.verts_from_bbox(bbox2))

                logger.info('vert_list1 = %r' % (vert_list1, ))
                logger.info('vert_list2 = %r' % (vert_list2, ))
                # for vx in [0, 1, 2, 3]:
                for vx in [0, 1]:
                    vert1 = vert_list1[vx].tolist()
                    vert2 = vert_list2[vx].tolist()
                    logger.info('  ***')
                    logger.info('  * vert1 = %r' % (vert1, ))
                    logger.info('  * vert2 = %r' % (vert2, ))

                    coordsA = coordsB = 'data'
                    # coords = 'axes points'
                    # 'axes fraction'
                    # 'axes pixels'
                    # coordsA = 'axes pixels'
                    # coordsB = 'data'
                    # 'figure fraction'
                    # 'figure pixels'
                    # 'figure pixels'
                    # 'figure points'
                    # 'polar'
                    # 'offset points'

                    con = mpl.patches.ConnectionPatch(
                        xyA=vert1,
                        xyB=vert2,
                        coordsA=coordsA,
                        coordsB=coordsB,
                        axesA=ax1,
                        axesB=ax2,
                        linewidth=1,
                        color='k',
                    )
                    # , arrowstyle="-")

                    # ut.embed()
                    # con.set_zorder(None)
                    ax1.add_artist(con)
                    # ax2.add_artist(con)

                    # ut.embed()

                    # verts2.T[1] -= bbox2[-1]
                    # bottom_left1, bottom_right1 = verts1[1:3].tolist()
                    # bottom_left2, bottom_right2 = verts2[1:3].tolist()

                # #transAxes1 = ax1.transData.inverted()
                # transAxes1_fn = ax1.transData.transform
                # transAxes2_fn = ax2.transData.transform

                # transAxes1_fn = ut.identity
                # transAxes2_fn = ut.identity

                # coord_bl1 = transFigure.transform(transAxes1.transform(bottom_left1))
                # coord_br1 = transFigure.transform(transAxes1.transform(bottom_right1))
                # coord_bl1 = invTransFigure_fn1(transAxes1_fn(bottom_left1))
                # logger.info('bottom_left2 = %r' % (bottom_left2,))
                # coord_bl1 = (5, 5)
                # coord_bl2 = invTransFigure_fn2(transAxes2_fn(bottom_left2))
                # logger.info('coord_bl2 = %r' % (coord_bl2,))

                # coord_br1 = invTransFigure_fn1(transAxes1_fn(bottom_right1))
                # coord_br2 = invTransFigure_fn2(transAxes2_fn(bottom_right2))
                # #logger.info('coord_bl1 = %r' % (coord_bl1,))

                # line_coords1 = np.vstack([coord_bl1, coord_bl2])
                # line_coords2 = np.vstack([coord_br1, coord_br2])
                # logger.info('line_coords1 = %r' % (line_coords1,))

                # line1 = mpl.lines.Line2D((line_coords1[0]), (line_coords1[1]), transform=fig.transFigure)
                # line2 = mpl.lines.Line2D((line_coords2[0]), (line_coords2[1]), transform=fig.transFigure)

                # xs1, ys1 = line_coords1.T
                # xs2, ys2 = line_coords2.T

                # linekw = dict(transform=fig.transFigure)
                # linekw = dict()

                # logger.info('xs1 = %r' % (xs1,))
                # logger.info('ys1 = %r' % (ys1,))

                # line1 = mpl.lines.Line2D(xs1, ys1, **linekw)
                # line2 = mpl.lines.Line2D(xs2, ys2, **linekw)  # NOQA
                # shrinkA=5, shrinkB=5, mutation_scale=20, fc="w")

                # ax2.add_artist(con)

                # fig.lines.append(line1)
                # fig.lines.append(line2)

        pass
    return fig
    def append_button(
        self,
        text,
        divider=None,
        rect=None,
        callback=None,
        size='9%',
        location='bottom',
        ax=None,
        **kwargs,
    ):
        """ Adds a button to the current page """
        if rect is not None:
            new_ax = df2.plt.axes(rect)
        if rect is None and divider is None:
            if ax is None:
                ax = df2.gca()
            divider = df2.ensure_divider(ax)
        if divider is not None:
            new_ax = divider.append_axes(location, size=size, pad=0.05)
        if callback is not None:
            color, hovercolor = '.85', '.95'
        else:
            color, hovercolor = '.88', '.88'
            # color, hovercolor = u'.45', u'.45'
        # if isinstance(text, six.text_type):
        new_but = mpl.widgets.Button(new_ax,
                                     text,
                                     color=color,
                                     hovercolor=hovercolor)
        # elif isinstance(text, (list, tuple)):
        #    labels = [False] * len(text)
        #    labels[0] = True
        #    new_but = mpl.widgets.CheckButtons(new_ax, text, labels)
        # else:
        #    raise ValueError('bad input')

        if callback is not None:
            new_but.on_clicked(callback)
        else:
            button_text = new_but.ax.texts[0]
            button_text.set_color('.6')
            # button_text.set_color('r')
            # ut.embed()
            # print('new_but.color = %r' % (new_but.color,))
        # else:
        # TODO: figure ou how to gray out these buttons
        #    new_but.color = u'.1'
        #    new_but.hovercolor = u'.1'
        #    new_but.active = False
        #    print('new_but.color = %r' % (new_but.color,))
        ph.set_plotdat(new_ax, 'viztype', 'button')
        ph.set_plotdat(new_ax, 'text', text)
        # ph.set_plotdat(new_ax, 'parent_axes', ax)
        if ax is not None:
            child_axes = ph.get_plotdat(ax, 'child_axes', [])
            child_axes.append(new_ax)
            ph.set_plotdat(ax, 'child_axes', child_axes)
        for key, val in six.iteritems(kwargs):
            ph.set_plotdat(new_ax, key, val)
        # Keep buttons from losing scrop
        tup = (new_but, new_ax)
        self.scope.append(tup)
        return tup