Ejemplo n.º 1
0
def draw_bayesian_model(model,
                        evidence={},
                        soft_evidence={},
                        fnum=None,
                        pnum=None,
                        **kwargs):

    from pgmpy.models import BayesianModel
    if not isinstance(model, BayesianModel):
        model = model.to_bayesian_model()

    import plottool as pt
    import networkx as nx
    kwargs = kwargs.copy()
    factor_list = kwargs.pop('factor_list', [])

    ttype_colors, ttype_scalars = make_colorcodes(model)

    textprops = {
        'horizontalalignment': 'left',
        'family': 'monospace',
        'size': 8,
    }

    # build graph attrs
    tup = get_node_viz_attrs(model, evidence, soft_evidence, factor_list,
                             ttype_colors, **kwargs)
    node_color, pos_list, pos_dict, takws = tup

    # draw graph
    has_infered = evidence or 'factor_list' in kwargs

    if False:
        fig = pt.figure(fnum=fnum, pnum=pnum, doclf=True)  # NOQA
        ax = pt.gca()
        drawkw = dict(pos=pos_dict,
                      ax=ax,
                      with_labels=True,
                      node_size=1100,
                      node_color=node_color)
        nx.draw(model, **drawkw)
    else:
        # BE VERY CAREFUL
        if 1:
            graph = model.copy()
            graph.__class__ = nx.DiGraph
            graph.graph['groupattrs'] = ut.ddict(dict)
            #graph = model.
            if getattr(graph, 'ttype2_cpds', None) is not None:
                # Add invis edges and ttype groups
                for ttype in model.ttype2_cpds.keys():
                    ttype_cpds = model.ttype2_cpds[ttype]
                    # use defined ordering
                    ttype_nodes = ut.list_getattr(ttype_cpds, 'variable')
                    # ttype_nodes = sorted(ttype_nodes)
                    invis_edges = list(ut.itertwo(ttype_nodes))
                    graph.add_edges_from(invis_edges)
                    nx.set_edge_attributes(
                        graph, 'style',
                        {edge: 'invis'
                         for edge in invis_edges})
                    nx.set_node_attributes(
                        graph, 'groupid',
                        {node: ttype
                         for node in ttype_nodes})
                    graph.graph['groupattrs'][ttype]['rank'] = 'same'
                    graph.graph['groupattrs'][ttype]['cluster'] = False
        else:
            graph = model
        pt.show_nx(graph,
                   layout_kw={'prog': 'dot'},
                   fnum=fnum,
                   pnum=pnum,
                   verbose=0)
        pt.zoom_factory()
        fig = pt.gcf()
        ax = pt.gca()
        pass
    hacks = [
        pt.draw_text_annotations(textprops=textprops, **takw) for takw in takws
        if takw
    ]

    xmin, ymin = np.array(pos_list).min(axis=0)
    xmax, ymax = np.array(pos_list).max(axis=0)
    if 'name' in model.ttype2_template:
        num_names = len(model.ttype2_template['name'].basis)
        num_annots = len(model.ttype2_cpds['name'])
        if num_annots > 4:
            ax.set_xlim((xmin - 40, xmax + 40))
            ax.set_ylim((ymin - 50, ymax + 50))
            fig.set_size_inches(30, 7)
        else:
            ax.set_xlim((xmin - 42, xmax + 42))
            ax.set_ylim((ymin - 50, ymax + 50))
            fig.set_size_inches(23, 7)
        title = 'num_names=%r, num_annots=%r' % (
            num_names,
            num_annots,
        )
    else:
        title = ''
    map_assign = kwargs.get('map_assign', None)

    def word_insert(text):
        return '' if len(text) == 0 else text + ' '

    top_assignments = kwargs.get('top_assignments', None)
    if top_assignments is not None:
        map_assign, map_prob = top_assignments[0]
        if map_assign is not None:
            title += '\n%sMAP: ' % (word_insert(kwargs.get('method', '')))
            title += map_assign + ' @' + '%.2f%%' % (100 * map_prob, )
    if kwargs.get('show_title', True):
        pt.set_figtitle(title, size=14)

    for hack in hacks:
        hack()

    if has_infered:
        # Hack in colorbars
        # if ut.list_type(basis) is int:
        #     pt.colorbar(scalars, colors, lbl='score', ticklabels=np.array(basis) + 1)
        # else:
        #     pt.colorbar(scalars, colors, lbl='score', ticklabels=basis)
        keys = ['name', 'score']
        locs = ['left', 'right']
        for key, loc in zip(keys, locs):
            if key in ttype_colors:
                basis = model.ttype2_template[key].basis
                # scalars =
                colors = ttype_colors[key]
                scalars = ttype_scalars[key]
                pt.colorbar(scalars,
                            colors,
                            lbl=key,
                            ticklabels=basis,
                            ticklocation=loc)
Ejemplo n.º 2
0
def show_model(model, evidence={}, soft_evidence={}, **kwargs):
    """
    References:
        http://stackoverflow.com/questions/22207802/pygraphviz-networkx-set-node-level-or-layer

    Ignore:
        pkg-config --libs-only-L libcgraph
        sudo apt-get  install libgraphviz-dev -y
        sudo apt-get  install libgraphviz4 -y

        # sudo apt-get install pkg-config
        sudo apt-get install libgraphviz-dev
        # pip install git+git://github.com/pygraphviz/pygraphviz.git
        pip install pygraphviz
        python -c "import pygraphviz; print(pygraphviz.__file__)"

        sudo pip3 install pygraphviz --install-option="--include-path=/usr/include/graphviz" --install-option="--library-path=/usr/lib/graphviz/"
        python3 -c "import pygraphviz; print(pygraphviz.__file__)"

    CommandLine:
        python -m ibeis.algo.hots.bayes --exec-show_model --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis.algo.hots.bayes import *  # NOQA
        >>> model = '?'
        >>> evidence = {}
        >>> soft_evidence = {}
        >>> result = show_model(model, evidence, soft_evidence)
        >>> print(result)
        >>> ut.quit_if_noshow()
        >>> import plottool as pt
        >>> ut.show_if_requested()
    """
    if ut.get_argval('--hackmarkov') or ut.get_argval('--hackjunc'):
        draw_tree_model(model, **kwargs)
        return

    import plottool as pt
    import networkx as netx
    fnum = pt.ensure_fnum(None)
    netx_graph = (model)
    #netx_graph.graph.setdefault('graph', {})['size'] = '"10,5"'
    #netx_graph.graph.setdefault('graph', {})['rankdir'] = 'LR'

    pos_dict = get_hacked_pos(netx_graph)
    #pos_dict = netx.pygraphviz_layout(netx_graph)
    #pos = netx.pydot_layout(netx_graph, prog='dot')
    #pos_dict = netx.graphviz_layout(netx_graph)

    textprops = {
        'family': 'monospace',
        'horizontalalignment': 'left',
        #'horizontalalignment': 'center',
        #'size': 12,
        'size': 8,
    }

    netx_nodes = model.nodes(data=True)
    node_key_list = ut.get_list_column(netx_nodes, 0)
    pos_list = ut.dict_take(pos_dict, node_key_list)

    var2_post = {f.variables[0]: f for f in kwargs.get('factor_list', [])}

    prior_text = None
    post_text = None
    evidence_tas = []
    post_tas = []
    prior_tas = []
    node_color = []

    has_infered = evidence or var2_post
    if has_infered:
        ignore_prior_with_ttype = ['score', 'match']
        show_prior = False
    else:
        ignore_prior_with_ttype = []
        #show_prior = True
        show_prior = False

    dpy = 5
    dbx, dby = (20, 20)
    takw1 = {'bbox_align': (.5, 0), 'pos_offset': [0, dpy], 'bbox_offset': [dbx, dby]}
    takw2 = {'bbox_align': (.5, 1), 'pos_offset': [0, -dpy], 'bbox_offset': [-dbx, -dby]}

    name_colors = pt.distinct_colors(max(model.num_names, 10))
    name_colors = name_colors[:model.num_names]

    #cmap_ = 'hot' #mx = 0.65 #mn = 0.15
    cmap_, mn, mx = 'plasma', 0.15, 1.0
    _cmap = pt.plt.get_cmap(cmap_)
    def cmap(x):
        return _cmap((x * mx) + mn)

    for node, pos in zip(netx_nodes, pos_list):
        variable = node[0]
        cpd = model.var2_cpd[variable]
        prior_marg = (cpd if cpd.evidence is None else
                      cpd.marginalize(cpd.evidence, inplace=False))

        show_evidence = variable in evidence
        show_prior = cpd.ttype not in ignore_prior_with_ttype
        show_post = variable in var2_post
        show_prior |= cpd.ttype not in ignore_prior_with_ttype

        post_marg = None

        if show_post:
            post_marg = var2_post[variable]

        def get_name_color(phi):
            order = phi.values.argsort()[::-1]
            if len(order) < 2:
                dist_next = phi.values[order[0]]
            else:
                dist_next = phi.values[order[0]] - phi.values[order[1]]
            dist_total = (phi.values[order[0]])
            confidence = (dist_total * dist_next) ** (2.5 / 4)
            #print('confidence = %r' % (confidence,))
            color = name_colors[order[0]]
            color = pt.color_funcs.desaturate_rgb(color, 1 - confidence)
            color = np.array(color)
            return color

        if variable in evidence:
            if cpd.ttype == 'score':
                cmap_index = evidence[variable] / (cpd.variable_card - 1)
                color = cmap(cmap_index)
                color = pt.lighten_rgb(color, .4)
                color = np.array(color)
                node_color.append(color)
            elif cpd.ttype == 'name':
                color = name_colors[evidence[variable]]
                color = np.array(color)
                node_color.append(color)
            else:
                color = pt.FALSE_RED
                node_color.append(color)
        #elif variable in soft_evidence:
        #    color = pt.LIGHT_PINK
        #    show_prior = True
        #    color = get_name_color(prior_marg)
        #    node_color.append(color)
        else:
            if cpd.ttype == 'name' and post_marg is not None:
                color = get_name_color(post_marg)
                node_color.append(color)
            elif cpd.ttype == 'match' and post_marg is not None:
                color = cmap(post_marg.values[1])
                color = pt.lighten_rgb(color, .4)
                color = np.array(color)
                node_color.append(color)
            else:
                #color = pt.WHITE
                color = pt.NEUTRAL
                node_color.append(color)

        if show_prior:
            if variable in soft_evidence:
                prior_color = pt.LIGHT_PINK
            else:
                prior_color = None
            prior_text = pgm_ext.make_factor_text(prior_marg, 'prior')
            prior_tas.append(dict(text=prior_text, pos=pos, color=prior_color, **takw2))
        if show_evidence:
            _takw1 = takw1
            if cpd.ttype == 'score':
                _takw1 = takw2
            evidence_text = cpd.variable_statenames[evidence[variable]]
            if isinstance(evidence_text, int):
                evidence_text = '%d/%d' % (evidence_text + 1, cpd.variable_card)
            evidence_tas.append(dict(text=evidence_text, pos=pos, color=color, **_takw1))
        if show_post:
            _takw1 = takw1
            if cpd.ttype == 'match':
                _takw1 = takw2
            post_text = pgm_ext.make_factor_text(post_marg, 'post')
            post_tas.append(dict(text=post_text, pos=pos, color=None, **_takw1))

    def trnps_(dict_list):
        """ tranpose dict list """
        list_dict = ut.ddict(list)
        for dict_ in dict_list:
            for key, val in dict_.items():
                list_dict[key + '_list'].append(val)
        return list_dict

    takw1_ = trnps_(post_tas + evidence_tas)
    takw2_ = trnps_(prior_tas)

    # Draw graph
    if has_infered:
        pnum1 = (3, 1, (slice(0, 2), 0))
    else:
        pnum1 = None

    fig = pt.figure(fnum=fnum, pnum=pnum1, doclf=True)  # NOQA
    ax = pt.gca()
    #print('node_color = %s' % (ut.repr3(node_color),))
    drawkw = dict(pos=pos_dict, ax=ax, with_labels=True, node_size=1500,
                  node_color=node_color)
    netx.draw(netx_graph, **drawkw)

    hacks = []
    if len(post_tas + evidence_tas):
        hacks.append(pt.draw_text_annotations(textprops=textprops, **takw1_))
    if prior_tas:
        hacks.append(pt.draw_text_annotations(textprops=textprops, **takw2_))

    xmin, ymin = np.array(pos_list).min(axis=0)
    xmax, ymax = np.array(pos_list).max(axis=0)
    num_annots = len(model.ttype2_cpds['name'])
    if num_annots > 4:
        ax.set_xlim((xmin - 40, xmax + 40))
        ax.set_ylim((ymin - 50, ymax + 50))
        fig.set_size_inches(30, 7)
    else:
        ax.set_xlim((xmin - 42, xmax + 42))
        ax.set_ylim((ymin - 50, ymax + 50))
        fig.set_size_inches(23, 7)
    fig = pt.gcf()

    title = 'num_names=%r, num_annots=%r' % (model.num_names, num_annots,)
    map_assign = kwargs.get('map_assign', None)

    top_assignments = kwargs.get('top_assignments', None)
    if top_assignments is not None:
        map_assign, map_prob = top_assignments[0]
        if map_assign is not None:
            def word_insert(text):
                return '' if len(text) == 0 else text + ' '
            title += '\n%sMAP: ' % (word_insert(kwargs.get('method', '')))
            title += map_assign + ' @' + '%.2f%%' % (100 * map_prob,)
    if kwargs.get('show_title', True):
        pt.set_figtitle(title, size=14)

    for hack in hacks:
        hack()

    # Hack in colorbars
    if has_infered:
        pt.colorbar(np.linspace(0, 1, len(name_colors)), name_colors, lbl='name',
                    ticklabels=model.ttype2_template['name'].basis, ticklocation='left')

        basis = model.ttype2_template['score'].basis
        scalars = np.linspace(0, 1, len(basis))
        scalars = np.linspace(0, 1, 100)
        colors = pt.scores_to_color(scalars, cmap_=cmap_, reverse_cmap=False,
                                    cmap_range=(mn, mx))
        colors = [pt.lighten_rgb(c, .4) for c in colors]

        if ut.list_type(basis) is int:
            pt.colorbar(scalars, colors, lbl='score', ticklabels=np.array(basis) + 1)
        else:
            pt.colorbar(scalars, colors, lbl='score', ticklabels=basis)
            #print('basis = %r' % (basis,))

    # Draw probability hist
    if has_infered and top_assignments is not None:
        bin_labels = ut.get_list_column(top_assignments, 0)
        bin_vals =  ut.get_list_column(top_assignments, 1)

        # bin_labels = ['\n'.join(ut.textwrap.wrap(_lbl, width=30)) for _lbl in bin_labels]

        pt.draw_histogram(bin_labels, bin_vals, fnum=fnum, pnum=(3, 8, (2, slice(4, None))),
                          transpose=True,
                          use_darkbackground=False,
                          #xtick_rotation=-10,
                          ylabel='Prob', xlabel='assignment')
        pt.set_title('Assignment probabilities')
Ejemplo n.º 3
0
def draw_bayesian_model(model, evidence={}, soft_evidence={}, fnum=None,
                        pnum=None, **kwargs):

    from pgmpy.models import BayesianModel
    if not isinstance(model, BayesianModel):
        model = model.to_bayesian_model()

    import plottool as pt
    import networkx as nx
    kwargs = kwargs.copy()
    factor_list = kwargs.pop('factor_list', [])

    ttype_colors, ttype_scalars = make_colorcodes(model)

    textprops = {
        'horizontalalignment': 'left', 'family': 'monospace', 'size': 8, }

    # build graph attrs
    tup = get_node_viz_attrs(
        model, evidence, soft_evidence, factor_list, ttype_colors, **kwargs)
    node_color, pos_list, pos_dict, takws = tup

    # draw graph
    has_infered = evidence or 'factor_list' in kwargs

    if False:
        fig = pt.figure(fnum=fnum, pnum=pnum, doclf=True)  # NOQA
        ax = pt.gca()
        drawkw = dict(pos=pos_dict, ax=ax, with_labels=True, node_size=1100,
                      node_color=node_color)
        nx.draw(model, **drawkw)
    else:
        # BE VERY CAREFUL
        if 1:
            graph = model.copy()
            graph.__class__ = nx.DiGraph
            graph.graph['groupattrs'] = ut.ddict(dict)
            #graph = model.
            if getattr(graph, 'ttype2_cpds', None) is not None:
                # Add invis edges and ttype groups
                for ttype in model.ttype2_cpds.keys():
                    ttype_cpds = model.ttype2_cpds[ttype]
                    # use defined ordering
                    ttype_nodes = ut.list_getattr(ttype_cpds, 'variable')
                    # ttype_nodes = sorted(ttype_nodes)
                    invis_edges = list(ut.itertwo(ttype_nodes))
                    graph.add_edges_from(invis_edges)
                    nx.set_edge_attributes(graph, 'style', {edge: 'invis' for edge in invis_edges})
                    nx.set_node_attributes(graph, 'groupid', {node: ttype for node in ttype_nodes})
                    graph.graph['groupattrs'][ttype]['rank'] = 'same'
                    graph.graph['groupattrs'][ttype]['cluster'] = False
        else:
            graph = model
        pt.show_nx(graph, layout_kw={'prog': 'dot'}, fnum=fnum, pnum=pnum, verbose=0)
        pt.zoom_factory()
        fig = pt.gcf()
        ax = pt.gca()
        pass
    hacks = [pt.draw_text_annotations(textprops=textprops, **takw)
             for takw in takws if takw]

    xmin, ymin = np.array(pos_list).min(axis=0)
    xmax, ymax = np.array(pos_list).max(axis=0)
    if 'name' in model.ttype2_template:
        num_names = len(model.ttype2_template['name'].basis)
        num_annots = len(model.ttype2_cpds['name'])
        if num_annots > 4:
            ax.set_xlim((xmin - 40, xmax + 40))
            ax.set_ylim((ymin - 50, ymax + 50))
            fig.set_size_inches(30, 7)
        else:
            ax.set_xlim((xmin - 42, xmax + 42))
            ax.set_ylim((ymin - 50, ymax + 50))
            fig.set_size_inches(23, 7)
        title = 'num_names=%r, num_annots=%r' % (num_names, num_annots,)
    else:
        title = ''
    map_assign = kwargs.get('map_assign', None)

    def word_insert(text):
        return '' if len(text) == 0 else text + ' '

    top_assignments = kwargs.get('top_assignments', None)
    if top_assignments is not None:
        map_assign, map_prob = top_assignments[0]
        if map_assign is not None:
            title += '\n%sMAP: ' % (word_insert(kwargs.get('method', '')))
            title += map_assign + ' @' + '%.2f%%' % (100 * map_prob,)
    if kwargs.get('show_title', True):
        pt.set_figtitle(title, size=14)

    for hack in hacks:
        hack()

    if has_infered:
        # Hack in colorbars
        # if ut.list_type(basis) is int:
        #     pt.colorbar(scalars, colors, lbl='score', ticklabels=np.array(basis) + 1)
        # else:
        #     pt.colorbar(scalars, colors, lbl='score', ticklabels=basis)
        keys = ['name', 'score']
        locs = ['left', 'right']
        for key, loc in zip(keys, locs):
            if key in ttype_colors:
                basis = model.ttype2_template[key].basis
                # scalars =
                colors = ttype_colors[key]
                scalars = ttype_scalars[key]
                pt.colorbar(scalars, colors, lbl=key, ticklabels=basis,
                            ticklocation=loc)
Ejemplo n.º 4
0
def draw_bayesian_model(model, evidence={}, soft_evidence={}, fnum=None,
                        pnum=None, **kwargs):

    from pgmpy.models import BayesianModel
    if not isinstance(model, BayesianModel):
        model = model.to_bayesian_model()

    import plottool as pt
    import networkx as netx
    factor_list = kwargs.get('factor_list', [])

    ttype_colors, ttype_scalars = make_colorcodes(model)

    textprops = {
        'horizontalalignment': 'left', 'family': 'monospace', 'size': 8, }

    # build graph attrs
    tup = get_node_viz_attrs(
        model, evidence, soft_evidence, factor_list, ttype_colors, **kwargs)
    node_color, pos_list, pos_dict, takws = tup

    # draw graph
    has_infered = evidence or 'factor_list' in kwargs

    fig = pt.figure(fnum=fnum, pnum=pnum, doclf=True)  # NOQA
    ax = pt.gca()
    drawkw = dict(pos=pos_dict, ax=ax, with_labels=True, node_size=1100,
                  node_color=node_color)
    netx.draw(model, **drawkw)
    hacks = [pt.draw_text_annotations(textprops=textprops, **takw)
             for takw in takws if takw]

    xmin, ymin = np.array(pos_list).min(axis=0)
    xmax, ymax = np.array(pos_list).max(axis=0)
    if 'name' in model.ttype2_template:
        num_names = len(model.ttype2_template['name'].basis)
        num_annots = len(model.ttype2_cpds['name'])
        if num_annots > 4:
            ax.set_xlim((xmin - 40, xmax + 40))
            ax.set_ylim((ymin - 50, ymax + 50))
            fig.set_size_inches(30, 7)
        else:
            ax.set_xlim((xmin - 42, xmax + 42))
            ax.set_ylim((ymin - 50, ymax + 50))
            fig.set_size_inches(23, 7)
        title = 'num_names=%r, num_annots=%r' % (num_names, num_annots,)
    else:
        title = ''
    map_assign = kwargs.get('map_assign', None)

    def word_insert(text):
        return '' if len(text) == 0 else text + ' '

    top_assignments = kwargs.get('top_assignments', None)
    if top_assignments is not None:
        map_assign, map_prob = top_assignments[0]
        if map_assign is not None:
            title += '\n%sMAP: ' % (word_insert(kwargs.get('method', '')))
            title += map_assign + ' @' + '%.2f%%' % (100 * map_prob,)
    if kwargs.get('show_title', True):
        pt.set_figtitle(title, size=14)

    for hack in hacks:
        hack()

    if has_infered:
        # Hack in colorbars
        # if ut.list_type(basis) is int:
        #     pt.colorbar(scalars, colors, lbl='score', ticklabels=np.array(basis) + 1)
        # else:
        #     pt.colorbar(scalars, colors, lbl='score', ticklabels=basis)
        keys = ['name', 'score']
        locs = ['left', 'right']
        for key, loc in zip(keys, locs):
            if key in ttype_colors:
                basis = model.ttype2_template[key].basis
                # scalars =
                colors = ttype_colors[key]
                scalars = ttype_scalars[key]
                pt.colorbar(scalars, colors, lbl=key, ticklabels=basis,
                            ticklocation=loc)
Ejemplo n.º 5
0
def show_model(model, evidence={}, soft_evidence={}, **kwargs):
    """
    References:
        http://stackoverflow.com/questions/22207802/pygraphviz-networkx-set-node-level-or-layer

    Ignore:
        pkg-config --libs-only-L libcgraph
        sudo apt-get  install libgraphviz-dev -y
        sudo apt-get  install libgraphviz4 -y

        # sudo apt-get install pkg-config
        sudo apt-get install libgraphviz-dev
        # pip install git+git://github.com/pygraphviz/pygraphviz.git
        pip install pygraphviz
        python -c "import pygraphviz; print(pygraphviz.__file__)"

        sudo pip3 install pygraphviz --install-option="--include-path=/usr/include/graphviz" --install-option="--library-path=/usr/lib/graphviz/"
        python3 -c "import pygraphviz; print(pygraphviz.__file__)"

    CommandLine:
        python -m ibeis.algo.hots.bayes --exec-show_model --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis.algo.hots.bayes import *  # NOQA
        >>> model = '?'
        >>> evidence = {}
        >>> soft_evidence = {}
        >>> result = show_model(model, evidence, soft_evidence)
        >>> print(result)
        >>> ut.quit_if_noshow()
        >>> import plottool as pt
        >>> ut.show_if_requested()
    """
    if ut.get_argval('--hackmarkov') or ut.get_argval('--hackjunc'):
        draw_tree_model(model, **kwargs)
        return

    import plottool as pt
    import networkx as netx
    fnum = pt.ensure_fnum(None)
    netx_graph = (model)
    #netx_graph.graph.setdefault('graph', {})['size'] = '"10,5"'
    #netx_graph.graph.setdefault('graph', {})['rankdir'] = 'LR'

    pos_dict = get_hacked_pos(netx_graph)
    #pos_dict = netx.nx_agraph.pygraphviz_layout(netx_graph)
    #pos = netx.nx_agraph.nx_pydot.pydot_layout(netx_graph, prog='dot')
    #pos_dict = netx.nx_agraph.graphviz_layout(netx_graph)

    textprops = {
        'family': 'monospace',
        'horizontalalignment': 'left',
        #'horizontalalignment': 'center',
        #'size': 12,
        'size': 8,
    }

    netx_nodes = model.nodes(data=True)
    node_key_list = ut.get_list_column(netx_nodes, 0)
    pos_list = ut.dict_take(pos_dict, node_key_list)

    var2_post = {f.variables[0]: f for f in kwargs.get('factor_list', [])}

    prior_text = None
    post_text = None
    evidence_tas = []
    post_tas = []
    prior_tas = []
    node_color = []

    has_inferred = evidence or var2_post
    if has_inferred:
        ignore_prior_with_ttype = [SCORE_TTYPE, MATCH_TTYPE]
        show_prior = False
    else:
        ignore_prior_with_ttype = []
        #show_prior = True
        show_prior = False

    dpy = 5
    dbx, dby = (20, 20)
    takw1 = {
        'bbox_align': (.5, 0),
        'pos_offset': [0, dpy],
        'bbox_offset': [dbx, dby]
    }
    takw2 = {
        'bbox_align': (.5, 1),
        'pos_offset': [0, -dpy],
        'bbox_offset': [-dbx, -dby]
    }

    name_colors = pt.distinct_colors(max(model.num_names, 10))
    name_colors = name_colors[:model.num_names]

    #cmap_ = 'hot' #mx = 0.65 #mn = 0.15
    cmap_, mn, mx = 'plasma', 0.15, 1.0
    _cmap = pt.plt.get_cmap(cmap_)

    def cmap(x):
        return _cmap((x * mx) + mn)

    for node, pos in zip(netx_nodes, pos_list):
        variable = node[0]
        cpd = model.var2_cpd[variable]
        prior_marg = (cpd if cpd.evidence is None else cpd.marginalize(
            cpd.evidence, inplace=False))

        show_evidence = variable in evidence
        show_prior = cpd.ttype not in ignore_prior_with_ttype
        show_post = variable in var2_post
        show_prior |= cpd.ttype not in ignore_prior_with_ttype

        post_marg = None

        if show_post:
            post_marg = var2_post[variable]

        def get_name_color(phi):
            order = phi.values.argsort()[::-1]
            if len(order) < 2:
                dist_next = phi.values[order[0]]
            else:
                dist_next = phi.values[order[0]] - phi.values[order[1]]
            dist_total = (phi.values[order[0]])
            confidence = (dist_total * dist_next)**(2.5 / 4)
            #print('confidence = %r' % (confidence,))
            color = name_colors[order[0]]
            color = pt.color_funcs.desaturate_rgb(color, 1 - confidence)
            color = np.array(color)
            return color

        if variable in evidence:
            if cpd.ttype == SCORE_TTYPE:
                cmap_index = evidence[variable] / (cpd.variable_card - 1)
                color = cmap(cmap_index)
                color = pt.lighten_rgb(color, .4)
                color = np.array(color)
                node_color.append(color)
            elif cpd.ttype == NAME_TTYPE:
                color = name_colors[evidence[variable]]
                color = np.array(color)
                node_color.append(color)
            else:
                color = pt.FALSE_RED
                node_color.append(color)
        #elif variable in soft_evidence:
        #    color = pt.LIGHT_PINK
        #    show_prior = True
        #    color = get_name_color(prior_marg)
        #    node_color.append(color)
        else:
            if cpd.ttype == NAME_TTYPE and post_marg is not None:
                color = get_name_color(post_marg)
                node_color.append(color)
            elif cpd.ttype == MATCH_TTYPE and post_marg is not None:
                color = cmap(post_marg.values[1])
                color = pt.lighten_rgb(color, .4)
                color = np.array(color)
                node_color.append(color)
            else:
                #color = pt.WHITE
                color = pt.NEUTRAL
                node_color.append(color)

        if show_prior:
            if variable in soft_evidence:
                prior_color = pt.LIGHT_PINK
            else:
                prior_color = None
            prior_text = pgm_ext.make_factor_text(prior_marg, 'prior')
            prior_tas.append(
                dict(text=prior_text, pos=pos, color=prior_color, **takw2))
        if show_evidence:
            _takw1 = takw1
            if cpd.ttype == SCORE_TTYPE:
                _takw1 = takw2
            evidence_text = cpd.variable_statenames[evidence[variable]]
            if isinstance(evidence_text, int):
                evidence_text = '%d/%d' % (evidence_text + 1,
                                           cpd.variable_card)
            evidence_tas.append(
                dict(text=evidence_text, pos=pos, color=color, **_takw1))
        if show_post:
            _takw1 = takw1
            if cpd.ttype == MATCH_TTYPE:
                _takw1 = takw2
            post_text = pgm_ext.make_factor_text(post_marg, 'post')
            post_tas.append(dict(text=post_text, pos=pos, color=None,
                                 **_takw1))

    def trnps_(dict_list):
        """ tranpose dict list """
        list_dict = ut.ddict(list)
        for dict_ in dict_list:
            for key, val in dict_.items():
                list_dict[key + '_list'].append(val)
        return list_dict

    takw1_ = trnps_(post_tas + evidence_tas)
    takw2_ = trnps_(prior_tas)

    # Draw graph
    if has_inferred:
        pnum1 = (3, 1, (slice(0, 2), 0))
    else:
        pnum1 = None

    fig = pt.figure(fnum=fnum, pnum=pnum1, doclf=True)  # NOQA
    ax = pt.gca()
    #print('node_color = %s' % (ut.repr3(node_color),))
    drawkw = dict(pos=pos_dict,
                  ax=ax,
                  with_labels=True,
                  node_size=1500,
                  node_color=node_color)
    netx.draw(netx_graph, **drawkw)

    hacks = []
    if len(post_tas + evidence_tas):
        hacks.append(pt.draw_text_annotations(textprops=textprops, **takw1_))
    if prior_tas:
        hacks.append(pt.draw_text_annotations(textprops=textprops, **takw2_))

    xmin, ymin = np.array(pos_list).min(axis=0)
    xmax, ymax = np.array(pos_list).max(axis=0)
    num_annots = len(model.ttype2_cpds[NAME_TTYPE])
    if num_annots > 4:
        ax.set_xlim((xmin - 40, xmax + 40))
        ax.set_ylim((ymin - 50, ymax + 50))
        fig.set_size_inches(30, 7)
    else:
        ax.set_xlim((xmin - 42, xmax + 42))
        ax.set_ylim((ymin - 50, ymax + 50))
        fig.set_size_inches(23, 7)
    fig = pt.gcf()

    title = 'num_names=%r, num_annots=%r' % (
        model.num_names,
        num_annots,
    )
    map_assign = kwargs.get('map_assign', None)

    top_assignments = kwargs.get('top_assignments', None)
    if top_assignments is not None:
        map_assign, map_prob = top_assignments[0]
        if map_assign is not None:

            def word_insert(text):
                return '' if len(text) == 0 else text + ' '

            title += '\n%sMAP: ' % (word_insert(kwargs.get('method', '')))
            title += map_assign + ' @' + '%.2f%%' % (100 * map_prob, )
    if kwargs.get('show_title', True):
        pt.set_figtitle(title, size=14)

    for hack in hacks:
        hack()

    # Hack in colorbars
    if has_inferred:
        pt.colorbar(np.linspace(0, 1, len(name_colors)),
                    name_colors,
                    lbl=NAME_TTYPE,
                    ticklabels=model.ttype2_template[NAME_TTYPE].basis,
                    ticklocation='left')

        basis = model.ttype2_template[SCORE_TTYPE].basis
        scalars = np.linspace(0, 1, len(basis))
        scalars = np.linspace(0, 1, 100)
        colors = pt.scores_to_color(scalars,
                                    cmap_=cmap_,
                                    reverse_cmap=False,
                                    cmap_range=(mn, mx))
        colors = [pt.lighten_rgb(c, .4) for c in colors]

        if ut.list_type(basis) is int:
            pt.colorbar(scalars,
                        colors,
                        lbl=SCORE_TTYPE,
                        ticklabels=np.array(basis) + 1)
        else:
            pt.colorbar(scalars, colors, lbl=SCORE_TTYPE, ticklabels=basis)
            #print('basis = %r' % (basis,))

    # Draw probability hist
    if has_inferred and top_assignments is not None:
        bin_labels = ut.get_list_column(top_assignments, 0)
        bin_vals = ut.get_list_column(top_assignments, 1)

        # bin_labels = ['\n'.join(ut.textwrap.wrap(_lbl, width=30)) for _lbl in bin_labels]

        pt.draw_histogram(
            bin_labels,
            bin_vals,
            fnum=fnum,
            pnum=(3, 8, (2, slice(4, None))),
            transpose=True,
            use_darkbackground=False,
            #xtick_rotation=-10,
            ylabel='Prob',
            xlabel='assignment')
        pt.set_title('Assignment probabilities')