def BNinference2dot(bn, size=None, engine=None, evs=None, targets=None, nodeColor=None, arcWidth=None, arcColor=None, cmapNode=None, cmapArc=None, dag=None): """ create a pydot representation of an inference in a BN Parameters ---------- bn : pyAgrum.BayesNet the Bayesian network size: str size of the rendered graph engine: pyAgrum.Inference inference algorithm used. If None, LazyPropagation will be used evs: dict map of evidence targets: set set of targets. If targets={} then each node is a target nodeColor: dict a nodeMap of values to be shown as color nodes (with special color for 0 and 1) arcWidth: dict a arcMap of values to be shown as bold arcs arcColor: dict a arcMap of values (between 0 and 1) to be shown as color of arcs cmapNode: ColorMap color map to show the vals of Nodes cmapArc: ColorMap color map to show the vals of Arcs dag : pyAgrum.DAG only shows nodes that have their id in the dag (and not in the whole BN) Returns ------- the desired representation of the inference """ if evs is None: evs = {} if targets is None: targets = {} if cmapNode is None: cmapNode = plt.get_cmap(gum.config["notebook", "default_node_cmap"]) if cmapArc is None: cmapArc = plt.get_cmap(gum.config["notebook", "default_arc_cmap"]) # defaukt maxarcs = 100 minarcs = 0 if arcWidth is not None: minarcs = min(arcWidth.values()) maxarcs = max(arcWidth.values()) startTime = time.time() if engine is None: ie = gum.LazyPropagation(bn) else: ie = engine ie.setEvidence(evs) ie.makeInference() stopTime = time.time() temp_dir = mkdtemp("", "tmp", None) # with TemporaryDirectory() as temp_dir: dotstr = "digraph structs {\n fontcolor=\"" + \ gumcols.getBlackInTheme() + "\";bgcolor=\"transparent\";" if gum.config["notebook", "show_inference_time"] == "True": dotstr += f" label=\"Inference in {1000 * (stopTime - startTime):6.2f}ms\";\n" dotstr += ' node [fillcolor="' + gum.config["notebook", "default_node_bgcolor"] + \ '", style=filled,color="' + \ gum.config["notebook", "default_node_fgcolor"] + '"];' + "\n" dotstr += ' edge [color="' + gumcols.getBlackInTheme() + '"];' + "\n" showdag = bn.dag() if dag is None else dag for nid in showdag.nodes(): name = bn.variable(nid).name() # defaults bgcol = gum.config["notebook", "default_node_bgcolor"] fgcol = gum.config["notebook", "default_node_fgcolor"] if len(targets) == 0 or name in targets or nid in targets: bgcol = gum.config["notebook", "figure_facecolor"] if nodeColor is not None: if name in nodeColor or nid in nodeColor: bgcol = gumcols.proba2bgcolor(nodeColor[name], cmapNode) fgcol = gumcols.proba2fgcolor(nodeColor[name], cmapNode) # 'hard' colour for evidence (?) if name in evs or nid in evs: bgcol = gum.config["notebook", "evidence_bgcolor"] fgcol = gum.config["notebook", "evidence_fgcolor"] colorattribute = f'fillcolor="{bgcol}", fontcolor="{fgcol}", color="#000000"' if len(targets) == 0 or name in targets or nid in targets: filename = temp_dir + \ hashlib.md5(name.encode()).hexdigest() + "." + \ gum.config["notebook", "graph_format"] proba_histogram.saveFigProba(ie.posterior(name), filename, bgcolor=bgcol) dotstr += f' "{name}" [shape=rectangle,image="{filename}",label="", {colorattribute}];\n' else: dotstr += f' "{name}" [{colorattribute}]' for a in showdag.arcs(): (n, j) = a if arcWidth is None: pw = 1 av = "" else: if (n, j) in arcWidth: if maxarcs == minarcs: pw = 1 else: pw = 0.1 + 5 * (arcWidth[a] - minarcs) / (maxarcs - minarcs) av = arcWidth[a] else: pw = 1 av = "" if arcColor is None: col = gumcols.getBlackInTheme() else: if a in arcColor: col = gumcols.proba2color(arcColor[a], cmapArc) else: col = gumcols.getBlackInTheme() dotstr += f' "{bn.variable(n).name()}"->"{bn.variable(j).name()}" [penwidth="{pw}",tooltip="{a}:{av}",color="{col}"];' dotstr += '}' g = dot.graph_from_dot_data(dotstr)[0] # workaround for some badly parsed graph (pyparsing>=3.03) g.del_node('"\\n"') if size is None: size = gum.config["notebook", "default_graph_inference_size"] g.set_size(size) g.temp_dir = temp_dir return g
def BN2dot(bn, size=None, nodeColor=None, arcWidth=None, arcColor=None, cmapNode=None, cmapArc=None, showMsg=None): """ create a pydot representation of the BN Parameters ---------- bn : pyAgrum.BayesNet the Bayesian network size: str size of the rendered graph nodeColor: dict a nodeMap of values to be shown as color nodes (with special color for 0 and 1) arcWidth: dict a arcMap of values to be shown as bold arcs arcColor: dict a arcMap of values (between 0 and 1) to be shown as color of arcs cmapNode: ColorMap color map to show the vals of Nodes cmapArc: ColorMap color map to show the vals of Arcs showMsg: dict a nodeMap of values to be shown as tooltip Returns ------- the desired representation of the Bayesian network """ if cmapNode is None: cmapNode = plt.get_cmap(gum.config["notebook", "default_node_cmap"]) if cmapArc is None: cmapArc = plt.get_cmap(gum.config["notebook", "default_arc_cmap"]) # default maxarcs = 100 minarcs = 0 if arcWidth is not None: minarcs = min(arcWidth.values()) maxarcs = max(arcWidth.values()) dotobj = dot.Dot(graph_type='digraph', bgcolor="transparent") for n in bn.names(): if nodeColor is None or n not in nodeColor: bgcol = gum.config["notebook", "default_node_bgcolor"] fgcol = gum.config["notebook", "default_node_fgcolor"] res = "" else: bgcol = gumcols.proba2bgcolor(nodeColor[n], cmapNode) fgcol = gumcols.proba2fgcolor(nodeColor[n], cmapNode) res = f" : {nodeColor[n] if showMsg is None else showMsg[n]:2.5f}" node = dot.Node('"' + n + '"', style="filled", fillcolor=bgcol, fontcolor=fgcol, tooltip=f'"({bn.idFromName(n)}) {n}{res}"') dotobj.add_node(node) for a in bn.arcs(): if arcWidth is None: pw = 1 av = "" else: if a in arcWidth: if maxarcs == minarcs: pw = 1 else: pw = 0.1 + 5 * (arcWidth[a] - minarcs) / (maxarcs - minarcs) av = arcWidth[a] else: pw = 1 av = 1 if arcColor is None: col = gumcols.getBlackInTheme() else: if a in arcColor: col = gumcols.proba2color(arcColor[a], cmapArc) else: col = gumcols.getBlackInTheme() edge = dot.Edge('"' + bn.variable(a[0]).name() + '"', '"' + bn.variable(a[1]).name() + '"', penwidth=pw, color=col, tooltip=f"{a} : {av}") dotobj.add_edge(edge) if size is None: size = gum.config["notebook", "default_graph_size"] # dynamic member makes pylink unhappy # pylint: disable=no-member dotobj.set_size(size) return dotobj
def MN2UGdot(mn, size="4", nodeColor=None, edgeWidth=None, edgeColor=None, cmapNode=None, cmapEdge=None, showMsg=None): """ Create a pydot representation of the Markov Network as an undirected graph Parameters ---------- mn : pyAgrum.MarkovNet The Markov network size : int |str Size of the rendered graph nodeColor : Dict[int,float] a nodeMap of values (between 0 and 1) to be shown as color of nodes (with special colors for 0 and 1) edgeWidth : Dict[Tuple(int,int),float] a edgeMap of values to be shown as width of edges edgeColor: Dict[Tuple(int,int),float] a edgeMap of values to be shown as color of edges cmapNode : matplotlib.color.colormap color map to show the vals of Nodes cmapEdge color map to show the vals of Edges. showMsg : Dict[int,str] a nodeMap of values to be shown as tooltip Returns ------- pydot.Dot the desired representation of the MN as a dot graph """ if cmapNode is None: cmapNode = plt.get_cmap(gum.config["notebook", "default_node_cmap"]) if cmapEdge is None: cmapEdge = plt.get_cmap(gum.config["notebook", "default_edge_cmap"]) # default maxedges = 100 minedges = 0 if edgeWidth is not None: minedges = min(edgeWidth.values()) maxedges = max(edgeWidth.values()) graph = dot.Dot(graph_type='graph', bgcolor="transparent") for n in mn.names(): if nodeColor is None or n not in nodeColor: bgcol = gum.config["notebook", "default_node_bgcolor"] fgcol = gum.config["notebook", "default_node_fgcolor"] res = "" else: bgcol = gumcols.proba2bgcolor(nodeColor[n], cmapNode) fgcol = gumcols.proba2fgcolor(nodeColor[n], cmapNode) res = f" : {nodeColor[n] if showMsg is None else showMsg[n]:2.5f}" node = dot.Node('"' + n + '"', style="filled", fillcolor=bgcol, fontcolor=fgcol, tooltip=f'"({mn.idFromName(n)}) {n}{res}"') graph.add_node(node) for a in mn.edges(): if edgeWidth is None: pw = 1 av = "" else: if a in edgeWidth: if maxedges == minedges: pw = 1 else: pw = 0.1 + 5 * (edgeWidth[a] - minedges) / (maxedges - minedges) av = edgeWidth[a] else: pw = 1 av = 1 if edgeColor is None: col = gumcols.getBlackInTheme() else: if a in edgeColor: col = gumcols.proba2color(edgeColor[a], cmapEdge) else: col = gumcols.getBlackInTheme() edge = dot.Edge('"' + mn.variable(a[0]).name() + '"', '"' + mn.variable(a[1]).name() + '"', penwidth=pw, color=col, tooltip=f"{a} : {av}") graph.add_edge(edge) if size is None: size = gum.config["notebook", "default_graph_size"] graph.set_size(size) return graph
def MNinference2FactorGraphdot(mn, size=None, engine=None, evs=None, targets=None, nodeColor=None, factorColor=None, cmapNode=None): """ create a pydot representation of an inference in a MN as an factor graph :param pyAgrum.MarkovNet mn: :param string size: size of the rendered graph :param pyAgrum Inference engine: inference algorithm used. If None, ShaferShenoyMNInference will be used :param dictionnary evs: map of evidence :param set targets: set of targets. If targets={} then each node is a target :param nodeColor: a nodeMap of values to be shown as color nodes (with special color for 0 and 1) :param cmapNode: color map to show the vals of Nodes :return: the desired representation of the inference """ if evs is None: evs = {} if targets is None: targets = {} if cmapNode is None: cmapNode = plt.get_cmap(gum.config["notebook", "default_node_cmap"]) startTime = time.time() if engine is None: ie = gum.ShaferShenoyMNInference(mn) else: ie = engine ie.setEvidence(evs) ie.makeInference() stopTime = time.time() from tempfile import mkdtemp temp_dir = mkdtemp("", "tmp", None) # with TemporaryDirectory() as temp_dir: dotstr = "graph {\n layout=\"neato\";\n fontcolor=\"" + \ gumcols.getBlackInTheme() + "\";bgcolor=\"transparent\";" if gum.config["notebook", "show_inference_time"] == "True": dotstr += f' label="Inference in {1000 * (stopTime - startTime):6.2f}ms";\n' dotstr += ' node [fillcolor="' + gum.config["notebook", 'default_node_bgcolor'] + \ '", style=filled,color="' + \ gum.config["notebook", "default_node_fgcolor"] + '"];' + "\n" dotstr += ' edge [color="' + gumcols.getBlackInTheme() + '"];' + "\n" for nid in mn.nodes(): name = mn.variable(nid).name() # defaults bgcol = gum.config["notebook", "default_node_bgcolor"] fgcol = gum.config["notebook", "default_node_fgcolor"] if len(targets) == 0 or name in targets or nid in targets: bgcol = gum.config["notebook", "figure_facecolor"] if nodeColor is not None: if name in nodeColor or nid in nodeColor: bgcol = gumcols.proba2bgcolor(nodeColor[name], cmapNode) fgcol = gumcols.proba2fgcolor(nodeColor[name], cmapNode) # 'hard' colour for evidence (?) if name in evs or nid in evs: bgcol = gum.config["notebook", "evidence_bgcolor"] fgcol = gum.config["notebook", "evidence_fgcolor"] colorattribute = f'fillcolor="{bgcol}", fontcolor="{fgcol}", color="#000000"' if len(targets) == 0 or name in targets or nid in targets: filename = temp_dir + \ hashlib.md5(name.encode()).hexdigest() + "." + \ gum.config["notebook", "graph_format"] saveFigProba(ie.posterior(name), filename, bgcolor=bgcol) dotstr += f' "{name}" [shape=rectangle,image="{filename}",label="", {colorattribute}];\n' else: dotstr += f' "{name}" [shape=rectangle,margin=0.04,width=0,height=0,{colorattribute}];\n' def factorname(f): return '"f' + "#".join(map(str, sorted(list(f)))) + '"' for f in mn.factors(): if factorColor is None: bgcol = gum.config["factorgraph", "default_factor_bgcolor"] else: bgcol = gumcols.proba2bgcolor(factorColor(f), cmapNode) dotstr += f' {factorname(f)} [style=filled,fillcolor={bgcol},shape=point,width=0.1,height=0.1];\n' for f in mn.factors(): col = gumcols.getBlackInTheme() for n in f: dotstr += f' {factorname(f)}->"{mn.variable(n).name()}" [tooltip="{f}:{n}",color="{col}",fillcolor="{bgcol}",len="{gum.config["factorgraph", "edge_length_inference"]}"];\n' dotstr += '}' g = dot.graph_from_dot_data(dotstr)[0] # workaround for some badly parsed graph (pyparsing>=3.03) g.del_node('"\\n"') if size is None: size = gum.config["notebook", "default_graph_inference_size"] g.set_size(size) g.temp_dir = temp_dir return g
def MNinference2UGdot(mn, size=None, engine=None, evs=None, targets=None, nodeColor=None, factorColor=None, arcWidth=None, arcColor=None, cmapNode=None, cmapArc=None, view=None): """ create a pydot representation of an inference in a MN as an UG :param pyAgrum.MarkovNet mn: :param string size: size of the rendered graph :param pyAgrum Inference engine: inference algorithm used. If None, ShaferShenoyMNInference will be used :param dictionnary evs: map of evidence :param set targets: set of targets. If targets={} then each node is a target :param nodeColor: a nodeMap of values to be shown as color nodes (with special color for 0 and 1) :param arcWidth: a arcMap of values to be shown as bold arcs :param arcColor: a arcMap of values (between 0 and 1) to be shown as color of arcs :param cmapNode: color map to show the vals of Nodes :param cmapArc: color map to show the vals of Arcs :return: the desired representation of the inference """ if evs is None: evs = {} if targets is None: targets = {} if cmapNode is None: cmapNode = plt.get_cmap(gum.config["notebook", "default_node_cmap"]) if cmapArc is None: cmapArc = plt.get_cmap(gum.config["notebook", "default_arc_cmap"]) # default minarcs = 0 maxarcs = 100 if arcWidth is not None: minarcs = min(arcWidth.values()) maxarcs = max(arcWidth.values()) startTime = time.time() if engine is None: ie = gum.ShaferShenoyMNInference(mn) else: ie = engine ie.setEvidence(evs) ie.makeInference() stopTime = time.time() from tempfile import mkdtemp temp_dir = mkdtemp("", "tmp", None) # with TemporaryDirectory() as temp_dir: dotstr = "graph structs {\n fontcolor=\"" + \ gumcols.getBlackInTheme() + "\";bgcolor=\"transparent\";" if gum.config["notebook", "show_inference_time"] == "True": dotstr += f' label="Inference in {1000 * (stopTime - startTime):6.2f}ms";\n' dotstr += ' node [fillcolor="' + gum.config["notebook", "default_node_bgcolor"] + \ '", style=filled,color="' + \ gum.config["notebook", "default_node_fgcolor"] + '"];' + "\n" dotstr += ' edge [color="' + gumcols.getBlackInTheme() + '"];' + "\n" for nid in mn.nodes(): name = mn.variable(nid).name() # defaults bgcol = gum.config["notebook", "default_node_bgcolor"] fgcol = gum.config["notebook", "default_node_fgcolor"] if len(targets) == 0 or name in targets or nid in targets: bgcol = gum.config["notebook", "figure_facecolor"] if nodeColor is not None: if name in nodeColor or nid in nodeColor: bgcol = gumcols.proba2bgcolor(nodeColor[name], cmapNode) fgcol = gumcols.proba2fgcolor(nodeColor[name], cmapNode) # 'hard' colour for evidence (?) if name in evs or nid in evs: bgcol = gum.config["notebook", "evidence_bgcolor"] fgcol = gum.config["notebook", "evidence_fgcolor"] colorattribute = f'fillcolor="{bgcol}", fontcolor="{fgcol}", color="#000000"' if len(targets) == 0 or name in targets or nid in targets: filename = temp_dir + \ hashlib.md5(name.encode()).hexdigest() + "." + \ gum.config["notebook", "graph_format"] saveFigProba(ie.posterior(name), filename, bgcolor=bgcol) dotstr += f' "{name}" [shape=rectangle,image="{filename}",label="", {colorattribute}];\n' else: dotstr += f' "{name}" [{colorattribute}]' for a in mn.edges(): (n, j) = a if arcWidth is None: pw = 1 av = "" else: if (n, j) in arcWidth: if maxarcs == minarcs: pw = 1 else: pw = 0.1 + 5 * (arcWidth[a] - minarcs) / (maxarcs - minarcs) av = arcWidth[a] else: pw = 1 av = "" if arcColor is None: col = gumcols.getBlackInTheme() else: if a in arcColor: col = gumcols.proba2color(arcColor[a], cmapArc) else: col = gumcols.getBlackInTheme() dotstr += f' "{mn.variable(n).name()}"--"{mn.variable(j).name()}" [penwidth="{pw}",tooltip="{a}:{av}",color="{col}"];' dotstr += '}' g = dot.graph_from_dot_data(dotstr)[0] # workaround for some badly parsed graph (pyparsing>=3.03) g.del_node('"\\n"') if size is None: size = gum.config["notebook", "default_graph_inference_size"] g.set_size(size) g.temp_dir = temp_dir return g
def MN2FactorGraphdot(mn, size=None, nodeColor=None, factorColor=None, cmapNode=None, showMsg=None): """ Create a pydot representation of the Markov Network as a factor graph Parameters ---------- mn: pyAgrum.MarkovNet the model size: float|str the size of the rendered graph nodeColor: Dict[str,float] a nodeMap of values (between 0 and 1) to be shown as color of nodes (with special colors for 0 and 1) factorColor: a function returning a value (between 0 and 1) to be shown as a color of factor. cmapNode: matplotlib.colors.Colormap colormap for nodes showMsg: Dict[str,str] a nodeMap of values to be shown as tooltip Returns ------- pydot.Dot the desired representation of the MN as a dot graph """ if cmapNode is None: cmapNode = plt.get_cmap(gum.config["notebook", "default_node_cmap"]) graph = dot.Dot(graph_type='graph', bgcolor="transparent", layout="neato") for n in mn.names(): if nodeColor is None or n not in nodeColor: bgcol = gum.config["factorgraph", "default_node_bgcolor"] fgcol = gum.config["factorgraph", "default_node_fgcolor"] res = "" else: bgcol = gumcols.proba2bgcolor(nodeColor[n], cmapNode) fgcol = gumcols.proba2fgcolor(nodeColor[n], cmapNode) res = f" : {nodeColor[n] if showMsg is None else showMsg[n]:2.5f}" node = dot.Node('"' + n + '"', style="filled", fillcolor=bgcol, fontcolor=fgcol, shape="rectangle", margin=0.04, width=0, height=0, tooltip=f'"({mn.idFromName(n)}) {n}{res}"') graph.add_node(node) def factorname(factor): return '"f' + "#".join(map(str, sorted(list(factor)))) + '"' for f in mn.factors(): if factorColor is None: bgcol = gum.config["factorgraph", "default_factor_bgcolor"] else: bgcol = gumcols.proba2bgcolor(factorColor(f), cmapNode) node = dot.Node(factorname(f), style="filled", fillcolor=bgcol, shape="point", width=0.1, height=0.1) graph.add_node(node) for f in mn.factors(): for n in f: edge = dot.Edge(factorname(f), '"' + mn.variable(n).name() + '"', color=gumcols.getBlackInTheme(), len=gum.config["factorgraph", "edge_length"]) graph.add_edge(edge) if size is None: size = gum.config["notebook", "default_graph_size"] graph.set_size(size) return graph
def _reprInformation(bn, evs=None, size=None, cmap=_INFOcmap, asString=False): """ repr a bn annotated with results from inference : Information and mutual information Parameters ---------- bn: pyAgrum.BayesNet the model evs: Dict[str|int,str|int|List[float]] the observations size: int|str size of the rendered graph cmap: matplotlib.colours.Colormap the cmap asString: bool returns the string or display the HTML Returns ------- str|None return the HTML string or directly display it. """ if size is None: size = gum.config["notebook", "default_graph_size"] if evs is None: evs = {} gr, mi, ma = getInformationGraph(bn, evs, size, cmap, withMinMax=True) # dynamic member makes pylink unhappy # pylint: disable=no-member gsvg = IPython.display.SVG(gr.create_svg(encoding="utf-8")) width = int(gsvg.data.split("width=")[1].split('"')[1].split("pt") [0]) / mpl.pyplot.rcParams['figure.dpi'] # pixel in inches if width < 5: width = 5 fig = mpl.figure.Figure(figsize=(width, 1)) fig.patch.set_alpha(0) canvas = fc(fig) ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) norm = mpl.colors.Normalize(vmin=mi, vmax=ma) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cmap, norm=norm, orientation='horizontal') cb1.set_label('Entropy') cb1.ax.text(mi, -2, f"{mi:.4f}", ha='left', va='top', color=gumcols.proba2bgcolor(0.01, cmap)) cb1.ax.text(ma, -2, f"{ma:.4f}", ha='right', va='top', color=gumcols.proba2bgcolor(0.99, cmap)) png = IPython.core.pylabtools.print_figure( canvas.figure, "png") # from IPython.core.pylabtools png_legend = f"<img style='vertical-align:middle' src='data:image/png;base64,{encodebytes(png).decode('ascii')}'>" sss = f"<div align='center'>{gsvg.data}<br/>{png_legend}</div>" if asString: return sss return IPython.display.display(IPython.display.HTML(sss))