def make_bivariate_graph(param, obs, observed=False, plate=False, scale=2): arrow_params = {"linewidth": 2, "head_width": 0.25} if param == "sigma": param_string = r"$\sigma$" elif param == "mu": param_string = r"$\mu$" else: param_string = param param_node = daft.Node("param", param_string, 1, 2.5, scale=scale) obs_node = daft.Node("obs", obs, 3.5, 2.5, scale=scale, observed=observed) obs_plate = daft.Plate([2.5, 1.5, 2, 2], label=r"$N$", position="bottom right") bivariate_model_graph = daft.PGM([5, 5], line_width=2, label_params={"fontsize": 32}) bivariate_model_graph.add_node(param_node) bivariate_model_graph.add_node(obs_node) bivariate_model_graph.add_edge("param", "obs", **arrow_params) if plate: bivariate_model_graph.add_plate(obs_plate) # Avoid fill with blue in newer versions of matplotlib bivariate_model_graph._plates[0].bbox["fc"] = "white" bivariate_model_graph.render() return bivariate_model_graph
def make_normal_model_graph(): arrow_params = {"linewidth": 2, "head_width": 0.25} mu_node = daft.Node("mu", r"$\mu$", 1, 2.5, scale=2) x_node = daft.Node("x", "x", 3.5, 2.5, scale=2, observed=True) x_plate = daft.Plate([2.5, 1.5, 2, 2], label=r"$N$", position="bottom right") normal_model_graph = daft.PGM([5, 5], line_width=2, label_params={"fontsize": 32}) normal_model_graph.add_node(mu_node) normal_model_graph.add_node(x_node) normal_model_graph.add_edge("mu", "x", **arrow_params) normal_model_graph.add_plate(x_plate) # Avoid fill with blue in newer versions of matplotlib normal_model_graph._plates[0].bbox["fc"] = "white" normal_model_graph.render() return normal_model_graph
def display_mdma_model(): s, asp = 3, 1.25 dose_node = daft.Node("dose", "MDMA\nDose", 1, 3, scale=s, aspect=asp) social_node = daft.Node("social_setting", "Social\nSetting", 1, 1, scale=s, aspect=asp) esteem_node = daft.Node("esteem", "Self\nEsteem", 5, 3, scale=s, aspect=asp) mood_node = daft.Node("mood", "Mood", 5, 1, scale=s, aspect=asp) mdma_model = daft.PGM([7, 4], line_width=4, label_params={ "fontsize": 16, "fontweight": "bold" }) nodes = [dose_node, social_node, esteem_node, mood_node] edges = [("dose", "esteem"), ("dose", "mood"), ("social_setting", "esteem"), ("social_setting", "mood")] [mdma_model.add_node(node) for node in nodes] [mdma_model.add_edge(*edge) for edge in edges] mdma_model.render()
def make_parameters_graph(observed=True, plate=False): arrow_params = {"linewidth": 2, "head_width": 0.25} in_nodes = [ daft.Node(f"theta_{ii}", f"$\\beta_{ii}$", 1, 4 - 1.5 * ii, scale=2, observed=observed) for ii in range(3) ] x_node = daft.Node("x", "x", 3.5, 2.5, scale=2, observed=False) parameters_graph = daft.PGM([5, 5], line_width=2, label_params={"fontsize": 32}) [parameters_graph.add_node(node) for node in in_nodes] parameters_graph.add_node(x_node) [ parameters_graph.add_edge(f"theta_{ii}", "x", **arrow_params) for ii in range(3) ] parameters_graph.render() return parameters_graph
def plot(self, layout=None, show_observed=False): layout = layout or Layout() layout.compute_dag(self.dag) from matplotlib import rc rc("font", family="serif", size=12) rc("text", usetex=True) import daft pgm = daft.PGM([layout.Lx, layout.Ly], origin=[0, 0]) nodes = nx.topological_sort(self.dag) n_nodes = len(nodes) id_obs = 0 for l_node, node in enumerate(nodes): x = layout.dag.node[node]["x"] y = layout.dag.node[node]["y"] fixed = isinstance(node, Factor) or isinstance(node, PlaceHolder) pgm.add_node(daft.Node( l_node, node.math(), x, y, fixed=fixed )) if isinstance(node, Likelihood): l_obs = n_nodes + id_obs pgm.add_node(daft.Node( l_obs, node.y_name, x + layout.dx, y, observed=True )) pgm.add_edge(l_node, l_obs) id_obs += 1 for source, target in self.dag.edges(): l_source = nodes.index(source) l_target = nodes.index(target) pgm.add_edge(l_source, l_target) pgm.render()
def daft_pooled(): # create the PGM pgm = daft.PGM(shape=[4, 2.5], origin=[0, 0], grid_unit=4, label_params={'fontsize': 18}) # priors pgm.add_node(daft.Node("beta", r"$\beta$", 1, 2, scale=2)) # Latent variable. pgm.add_node(daft.Node("mu", r"$\beta X_{n}$", 1, 1, scale=2)) # noise pgm.add_node(daft.Node("epsilon", r"$\epsilon$", 3, 1, scale=2)) # observed data pgm.add_node(daft.Node("y", r"$y_n$", 2, 1, scale=2, observed=True)) # edges pgm.add_edge("beta", "mu") pgm.add_edge("mu", "y") pgm.add_edge("epsilon", "y") # plate pgm.add_plate( daft.Plate([0.5, 0.6, 2, 0.9], label=r"$n \in 1:N$", shift=-0.1)) pgm.render() plt.show()
def simple(): # Instantiate a PGM. pgm = daft.PGM([3.3, 3.0], origin=[0.3, 0.3], grid_unit=2.6, node_unit=1.3, observed_style="inner") # Model parameters: pgm.add_node(daft.Node("a", r"$a$", 0.8, 2.8)) pgm.add_node(daft.Node("b", r"$b$", 1.8, 2.8)) # Latent variable - intrinsic magnitude: pgm.add_node(daft.Node("m", r"$m_k$", 1.3, 1.4, fixed=True, offset=(0,-25))) # Data - observed magnitude: pgm.add_node(daft.Node("mobs", r"$m^{\rm obs}_k$", 2.5, 1.4, observed=True)) # Constants - magnitude errors: pgm.add_node(daft.Node("merr", r"$\sigma_k$", 1.9, 0.9, fixed=True, offset=(-3,0))) # Add in the edges. pgm.add_edge("a", "m") pgm.add_edge("b", "m") pgm.add_edge("merr", "mobs") pgm.add_edge("m", "mobs") # And a plate for the pixels pgm.add_plate(daft.Plate([0.5, 0.7, 2.7, 1.4], label=r"cepheids $k$", shift=-0.1)) # Render and save. pgm.render() pgm.figure.savefig("cepheids_pgm.png", dpi=300) return
def make_figure_8p1(): """Make the intro graph.""" pgm = daft.PGM([2.5, 2.5], origin=[-0.3, -0.3]) pgm.add_node(daft.Node("a", r"a", 1., 1.8, observed=True)) pgm.add_node(daft.Node("b", r"b", 0.2, 0.2, observed=True)) pgm.add_node(daft.Node("c", r"c", 1.8, 0.2, observed=True)) pgm.add_edge("a", "b") pgm.add_edge("b", "c") pgm.add_edge("a", "c") pgm.render() pgm.figure.savefig("figures/fig_8p1.pdf")
def make_figure_8p13(): """Create a graph like figure 8.13.""" pgm = daft.PGM([3, 2], origin=[-0.3, -0.3]) pgm.add_node(daft.Node("x1", r"$x_1$", 0.2, 1.3, observed=True)) pgm.add_node(daft.Node("xm", r"$x_M$", 1.8, 1.3, observed=True)) pgm.add_node(daft.Node("y", r"$y$", 1.0, 0.3, observed=True)) pgm.add_edge("x1", "xm", directed=False, ls=":") pgm.add_edge("x1", "y") pgm.add_edge("xm", "y") pgm.render() pgm.figure.savefig("figures/fig_8p13.pdf")
def plot_gmm_plate(filename="gmm.png", dpi=100): pgm = daft.PGM([3.0, 2.5], origin=(0, 0)) pgm.add_node(daft.Node("theta", r"$\mathbf{\theta}$", 1, 2, fixed=True)) pgm.add_node(daft.Node("ti", r"$\mathbf{t}_i$", 1, 1)) pgm.add_node(daft.Node("xi", r"$\mathbf{x}_i$", 2, 1, observed=True)) pgm.add_edge("theta", "ti") pgm.add_edge("theta", "xi") pgm.add_edge("ti", "xi") pgm.add_plate(daft.Plate([0.4, 0.5, 2.2, 1.0], label=r"$N$")) ax = pgm.render() ax.text(0.8, 0.5, 'Gaussian mixture model') pgm.savefig(filename, dpi=dpi)
def make_figure_8p11(): """Create a graph like figure 8.11.""" pgm = daft.PGM([3, 2], origin=[-0.3, -0.3]) pgm.add_node(daft.Node("mu1", r"$\mu_1$", 0.2, 1.3, observed=False)) pgm.add_node(daft.Node("mu2", r"$\mu_2$", 1.8, 1.3, observed=False)) pgm.add_node( daft.Node("x1", r"$\boldsymbol{x}_1$", 0.2, 0.3, observed=True)) pgm.add_node( daft.Node("x2", r"$\boldsymbol{x}_2$", 1.8, 0.3, observed=True)) pgm.add_edge("x1", "x2") pgm.add_edge("mu1", "x1") pgm.add_edge("mu2", "x2") pgm.render() pgm.figure.savefig("figures/fig_8p11.pdf")
def weakLensing(): pgm = daft.PGM([4.7, 2.35], origin=[-1.35, 2.2]) pgm.add_node(daft.Node("Omega", r"$\Omega$", -1, 4)) pgm.add_node(daft.Node("rho", r"$\rho$", 0, 4)) pgm.add_node( daft.Node("obs", r"$\epsilon^{\mathrm{obs}}_n$", 1, 4, observed=True)) pgm.add_node(daft.Node("alpha", r"$\alpha$", 3, 4)) pgm.add_node(daft.Node("true", r"$\epsilon^{\mathrm{true}}_n$", 2, 4)) pgm.add_node(daft.Node("sigma", r"$\sigma_n$", 1, 3)) pgm.add_node(daft.Node("Sigma", r"$\Sigma$", 0, 3)) pgm.add_node(daft.Node("x", r"$x_n$", 2, 3, observed=True)) pgm.add_plate(daft.Plate([0.5, 2.25, 2, 2.25], label=r"galaxies $n$")) pgm.add_edge("Omega", "rho") pgm.add_edge("rho", "obs") pgm.add_edge("alpha", "true") pgm.add_edge("true", "obs") pgm.add_edge("x", "obs") pgm.add_edge("Sigma", "sigma") pgm.add_edge("sigma", "obs") pgm.render() pgm.figure.savefig("weaklensing.pdf")
def make_figure_8p9(): """Create a pair of graphs like figure 8.9.""" pgm = daft.PGM([3, 2], origin=[-0.3, -0.3]) pgm.add_node( daft.Node("x11", r"$\boldsymbol{x}_1$", 0.2, 1.3, observed=True)) pgm.add_node( daft.Node("x21", r"$\boldsymbol{x}_2$", 1.8, 1.3, observed=True)) pgm.add_node( daft.Node("x12", r"$\boldsymbol{x}_1$", 0.2, 0.3, observed=True)) pgm.add_node( daft.Node("x22", r"$\boldsymbol{x}_2$", 1.8, 0.3, observed=True)) pgm.add_edge("x11", "x21") pgm.render() pgm.figure.savefig("figures/fig_8p9.pdf")
def make_anova_graph(group_observed=True, value_observed=False, params_known=True): group = daft.Node("$g$", "$g$", x=3, y=6, observed=group_observed, scale=3) value = daft.Node("$y$", "$y$", x=6, y=6, observed=value_observed, scale=3) group_params = daft.Node("$A$", "$A$", observed=params_known, x=3, y=3, scale=3) shared_param1 = daft.Node("$\sigma$", "$\sigma$", observed=params_known, x=4.5, y=9, scale=3) shared_param2 = daft.Node(r"$\mu_{G}$", r"$\mu_{G}$", observed=params_known, x=2.5, y=9, scale=3) nodes = [group, value, group_params, shared_param1, shared_param2] edges = [("$g$", "$y$"), ("$A$", "$y$"), ("$\sigma$", "$y$"), (r"$\mu_{G}$", "$y$")] graph = daft.PGM(shape=(9, 12), label_params={"fontsize": "xx-large"}) within_group_plate = daft.Plate([1.5, 4.5, 6, 3], label="$N$", position="bottom right", rect_params={"lw": 2}) between_group_plate = daft.Plate([1, 1, 7, 7], label="$K$", position="bottom right", rect_params={"lw": 2}) plates = [within_group_plate, between_group_plate] [graph.add_node(node) for node in nodes] [graph.add_edge(*edge, head_width=0.5, lw=4) for edge in edges] [graph.add_plate(plate) for plate in plates] shared_util.clean_plates(graph) graph.render()
def make_mixture_plateless_graph(): obs = [1, 2, 3] groups = [1, 2] group_nodes = [ daft.Node(f"$g_{i}$", f"$g_{i}$", x=3, y=3.5 * i, observed=True, scale=3) for i in obs ] observed_nodes = [ daft.Node(f"$x_{i}$", f"$x_{i}$", x=6, y=3.5 * i, observed=False, scale=3) for i in obs ] group_params = [ daft.Node(f"$\lambda_{k}$", f"$\lambda_{k}$", observed=True, x=8, y=4 + 2 * k, scale=2.5) for k in groups ] shared_param = daft.Node("$\\beta$", "$\\beta$", x=12, y=7, observed=True, scale=3) nodes = group_nodes + observed_nodes + group_params + [shared_param] observation_edges = [(f"$g_{i}$", f"$x_{i}$") for i in obs] group_param_edges = [(f"$\lambda_{k}$", f"$x_{i}$") for i, k in itertools.product(obs, groups)] shared_param_edges = [("$\\beta$", f"$x_{i}$") for i in obs] edges = observation_edges + group_param_edges + shared_param_edges graph = daft.PGM(shape=(15, 12), label_params={"fontsize": "xx-large"}) [graph.add_node(node) for node in nodes] [graph.add_edge(*edge, head_width=0.5, lw=4) for edge in edges] graph.render()
def make_figure_8p5(): """Create a graph like figure 8.5.""" pgm = daft.PGM([3.5, 2.5], origin=[-0.3, -0.3]) pgm.add_node(daft.Node("s2", r"$\sigma^2$", 0.2, 0.2, fixed=True)) pgm.add_node(daft.Node("xn", r"$x_n$", 1.5, 1.6, fixed=True)) pgm.add_node(daft.Node("tn", r"$t_n$", 1.5, 0.2, observed=True)) pgm.add_node(daft.Node("w", r"$\boldsymbol{w}$", 2.5, 0.2)) pgm.add_node(daft.Node("alpha", r"$\alpha$", 2.5, 1.6, fixed=True)) pgm.add_plate(daft.Plate([0.8, 0.0, 1.2, 1.9], label=r"$N$", shift=-0.1)) pgm.add_edge("s2", "tn") pgm.add_edge("xn", "tn") pgm.add_edge("w", "tn") pgm.add_edge("alpha", "w") pgm.render() pgm.figure.savefig("figures/fig_8p5.pdf")
def make_task_bn(): pgm = daft.PGM([5, 3]) pgm.add_node(daft.Node("duration", r"$D$", 2.5, 2.5)) pgm.add_node(daft.Node("earliest start", r"$ES$", 4.5, 1.5, observed=True)) pgm.add_node(daft.Node("latest start", r"$LS$", 0.5, 1.5)) pgm.add_node(daft.Node("earliest finish", r"$EF$", 3.5, 0.5)) pgm.add_node(daft.Node("latest finish", r"$LF$", 1.5, 0.5, observed=True)) pgm.add_edge("duration", "latest start") pgm.add_edge("duration", "earliest finish") pgm.add_edge("earliest start", "earliest finish") pgm.add_edge("latest finish", "latest start") pgm.render() pgm.figure.savefig("task_bn.png", dpi=300)
def daft_hier(): # create the PGM pgm = daft.PGM(shape=[7, 2.5], origin=[0, 0], grid_unit=4, label_params={'fontsize': 18}) # priors pgm.add_node(daft.Node("beta_parent_mu", r"$\mu_{parent}$", 1, 1, scale=2)) pgm.add_node( daft.Node("beta_parent_sd", r"$\sigma_{parent}$", 2, 2.2, scale=2)) pgm.add_node(daft.Node("beta_mfr_mu", r"$\mu_{mfr}$", 2, 1, scale=2)) pgm.add_node(daft.Node("beta_mfr_sd", r"$\sigma_{mfr}$", 3, 2.2, scale=2)) pgm.add_node(daft.Node("beta_mfr", r"$\beta_{mfr}$", 3, 1, scale=2)) pgm.add_node(daft.Node("beta", r"$\beta$", 4, 2.2, scale=2)) # latent variable. pgm.add_node(daft.Node("mu", r"$\beta X_{n}$", 4, 1, scale=2)) # noise pgm.add_node(daft.Node("epsilon", r"$\epsilon$", 6.2, 1, scale=2)) # observed data pgm.add_node(daft.Node("y", r"$y_n$", 5, 1, scale=2, observed=True)) # edges pgm.add_edge("beta_parent_mu", "beta_mfr_mu") pgm.add_edge("beta_parent_sd", "beta_mfr_mu") pgm.add_edge("beta_mfr_mu", "beta_mfr") pgm.add_edge("beta_mfr_sd", "beta_mfr") pgm.add_edge("beta_mfr", "mu") pgm.add_edge("beta", "mu") pgm.add_edge("mu", "y") pgm.add_edge("epsilon", "y") # plates pgm.add_plate( daft.Plate([3.5, 0.6, 2, 0.9], label=r"$n \in 1:N$", shift=-0.1)) pgm.add_plate( daft.Plate([2.5, 0.5, 3.1, 1.1], label=r"$mfr \in 1:N_{mfr}$", shift=-0.1)) pgm.add_plate( daft.Plate([1.5, 0.4, 4.2, 1.3], label=r"$parent \in 1:N_{parent}$", shift=-0.1)) pgm.render() plt.show()
def show_model(self): """Render the model as a Bayes net using daft.""" import daft gray = ".3" pgm = daft.PGM((3.5, 4), node_ec=gray) scale = 1.5 pgm.add_node(daft.Node("k", r"$k$", 1.5, 3.5, scale)) pgm.add_node(daft.Node("vim1", r"$v_{i-1}$", .5, 2.5, scale)) pgm.add_node(daft.Node("vi", r"$v_i$", 2.5, 2.5, scale)) pgm.add_node(daft.Node("pim1", r"$p_{i-1}$", 1, 1.5, scale)) pgm.add_node(daft.Node("pi", r"$p_i$", 3, 1.5, scale)) pgm.add_node( daft.Node("yim1", r"$y_{i-1}$", 1, .5, scale, observed=True)) pgm.add_node(daft.Node("yi", r"$y_i$", 3, .5, scale, observed=True)) pgm.add_edge("k", "vim1") pgm.add_edge("k", "vi") pgm.add_edge("vim1", "pim1") pgm.add_edge("vi", "pi") pgm.add_edge("vim1", "vi") pgm.add_edge("pim1", "pi") pgm.add_edge("pim1", "yim1") pgm.add_edge("pi", "yi") pgm.render() return pgm
def pgms_triangles(option='a-c-d'): """ Draws one of two triangular PGMs. Parameters ---------- option: string which PGM to draw, 'a-c-d' or 'c-y-d' """ # Start diagram: import daft pgm = daft.PGM([2.3, 1.9], origin=[0.2, 0.6], grid_unit=2.6, node_unit=1.0, observed_style="inner") # Parameter: pgm.add_node(daft.Node("theta", r"$\theta$", 1.3, 2)) # Latent variable: pgm.add_node(daft.Node("c", r"$c$", 0.6, 1, fixed=True, offset=(-7, 4))) # Data: pgm.add_node(daft.Node("d", r"$d$", 2, 1)) # Add in the edges. pgm.add_edge("theta", "c") pgm.add_edge("c", "d") if option == 'a-c-d': pgm.add_edge('theta', 'd') elif option == 'c-y-d': pgm.add_edge('d', 'theta') else: assert False # Render and save. pgm.render() outfile = "pgms_" + option + ".png" pgm.figure.savefig(outfile, dpi=300) return
def make_science_model_graph(observed=True, plate=False): arrow_params = {"linewidth": 2, "head_width": 0.25} label_params = {"fontsize": "small"} hypothesis_node = daft.Node( "hypothesis", r"$H_0$", 1.5, 2.5, scale=2.2, #aspect=1.5, label_params=label_params) result_node = daft.Node("result", "Result", 4, 2.5, scale=2.2, observed=observed, label_params=label_params) result_plate = daft.Plate([2.5, 1.5, 2, 2], label=r"$N$", position="bottom right") science_model_graph = daft.PGM([5, 5], line_width=2, label_params={"fontsize": 32}) science_model_graph.add_node(hypothesis_node) science_model_graph.add_node(result_node) science_model_graph.add_edge("hypothesis", "result", **arrow_params) if plate: science_model_graph.add_plate(result_plate) # Avoid fill with blue in newer versions of matplotlib science_model_graph._plates[0].bbox["fc"] = "white" science_model_graph.render() plt.tight_layout() return science_model_graph
def inverse(): # Instantiate a PGM. pgm = daft.PGM([3.3, 3.0], origin=[0.3, 0.3], grid_unit=2.6, node_unit=1.3, observed_style="inner") # Model parameters. pgm.add_node(daft.Node("theta", r"$\theta$", 1.7, 2.8)) # Latent variable: Poisson mean in kth pixel pgm.add_node( daft.Node("mean", r"$\mu_k$", 1.7, 1.7, fixed=True, offset=(-12, 0))) # Constants - ex and pb pgm.add_node(daft.Node("ex", r"ex$_k$", 0.9, 1.7, fixed=True)) pgm.add_node( daft.Node("pb", r"pb$_k$", 1.3, 1.1, fixed=True, offset=(-8, 0))) # Data - counts in kth pixel: pgm.add_node(daft.Node("counts", r"$N_k$", 2.7, 1.7, observed=True)) # Add in the edges. pgm.add_edge("theta", "mean") pgm.add_edge("ex", "mean") pgm.add_edge("pb", "mean") pgm.add_edge("mean", "counts") # And a plate for the pixels pgm.add_plate( daft.Plate([0.5, 0.7, 2.7, 1.7], label=r"pixels $k$", shift=-0.1)) # Render and save. pgm.render() pgm.figure.savefig("cluster_pgm_inverse.png", dpi=300) return
def recurse(pgm, nodename, level, c): if level > 4: return nodename r = c // 2 r1nodename = "r{0:02d}{1:04d}".format(level, r) if 2 * r == c: print("adding {0}".format(r1nodename)) pgm.add_node(daft.Node(r1nodename, r"reduce", 2 ** level * (r + 0.5) - 0.5, 3 - 0.7 * level, aspect=1.9)) pgm.add_edge(nodename, r1nodename) if 2 * r == c: return recurse(pgm, r1nodename, level + 1, r)
def show_model(self): """Render the model as a Bayes net using daft.""" import daft gray = ".3" pgm = daft.PGM((3, 3), node_ec=gray) scale = 1.5 pgm.add_node(daft.Node("v", r"$v$", 1.5, 2.5, scale)) pgm.add_node(daft.Node("pim1", r"$p_{i-1}$", .5, 1.5, scale)) pgm.add_node(daft.Node("pi", r"$p_i$", 2.5, 1.5, scale)) pgm.add_node(daft.Node("yim1", r"$y_{i-1}$", .5, .5, scale, observed=True)) pgm.add_node(daft.Node("yi", r"$y_i$", 2.5, .5, scale, observed=True)) kws = {"plot_params": {"ec": gray, "fc": gray}} pgm.add_edge("v", "pim1", **kws) pgm.add_edge("v", "pi", **kws) pgm.add_edge("pim1", "pi", **kws) pgm.add_edge("pim1", "yim1", **kws) pgm.add_edge("pi", "yi", **kws) pgm.render() return pgm
def run(): pgm = daft.PGM([7, 2]) class_node = pgm.add_node( daft.Node("spam?", "spam?", y=1.5, x=(ASPECT / 2 + 0.1) * 2.5, aspect=ASPECT)) words = ["offer", "money", "investment", "consultation"] for idx, word in enumerate(words): node = daft.Node(word, word, y=0.5, x=(ASPECT / 2 + 0.1) * (idx + 1), aspect=ASPECT) pgm.add_node(node) pgm.add_edge("spam?", word, directed=True) pgm.render()
def display_huth_model(): s, asp = 3, 1.25 empty_params = {"linewidth": 0} semantic_node = daft.Node("semantic", "Semantic\nContent", 1, 3, scale=s, aspect=asp) voxel1_node = daft.Node("voxel1", "voxel1", 5, 5, scale=s, aspect=asp) empty1_node = daft.Node("empty1", "", 5, 4, scale=s, aspect=asp, plot_params=empty_params) ellipsis = daft.Node("ellipsis", "...", 5, 3, scale=s, aspect=asp, plot_params=empty_params) emptyN_node = daft.Node("emptyN", "", 5, 2, scale=s, aspect=asp, plot_params=empty_params) voxelN_node = daft.Node("voxelN", "voxelN", 5, 1, scale=s, aspect=asp) huth_model = daft.PGM([7, 6], line_width=4, label_params={ "fontsize": 16, "fontweight": "bold" }) nodes = [ voxel1_node, voxelN_node, semantic_node, ellipsis, empty1_node, emptyN_node ] edges = [("semantic", "voxel1"), ("semantic", "empty1"), ("semantic", "ellipsis"), ("semantic", "emptyN"), ("semantic", "voxelN")] [huth_model.add_node(node) for node in nodes] [huth_model.add_edge(*edge) for edge in edges] huth_model.render()
def pgm(path): from matplotlib import rc rc("font", family="serif", size=12) import daft pgm = daft.PGM([3.3, 3.1], origin=[0.4, 0.3]) # First round pgm.add_node(daft.Node("alpha", r"$\alpha$", 1, 3, fixed=True)) pgm.add_node(daft.Node("theta", r"$\theta$", 1, 2)) pgm.add_node(daft.Node("X", r"$X$", 1, 1, observed=True)) # Second rounds pgm.add_node(daft.Node("beta", r"$\beta$", 3, 3, fixed=True)) pgm.add_node(daft.Node("pi", r"$\pi_{AB}$", 3, 2)) pgm.add_node(daft.Node("Y", r"$Y_{AB}$", 3, 1, observed=True)) # Middle part pgm.add_node(daft.Node("S", r"$S_{AB}$", 2, 2.5)) pgm.add_node(daft.Node("T", r"$T$", 2, 1.5)) pgm.add_edge("alpha", "theta") pgm.add_edge("theta", "X") pgm.add_edge("beta", "pi") pgm.add_edge("pi", "Y") pgm.add_edge("theta", "T") pgm.add_edge("theta", "S") pgm.add_edge("S", "T") pgm.add_edge("pi", "T") # First round polls #pgm.add_plate(daft.Plate([0.5, 0.5, 1, 1])) # Second round polls #pgm.add_plate(daft.Plate([2.5, 0.5, 1, 1])) # Second rounds pgm.add_plate(daft.Plate([2.4, 0.4, 1.2, 2.2])) # Render and save. pgm.render() pgm.figure.savefig(path, dpi=300)
def plot_hierarchy(all_matrices, arch, asp=1, nu=0.4, gu=4): ''' arch: list of hidden layers and DEGs all_matrices: list of numpy ndarray matrices for arch above ''' pgm = daft.PGM([np.max(arch), len(arch)], origin=[.5, .5], node_unit=nu, grid_unit=gu, directed=True) # pgm = daft.PGM([arch[-1]+1,len(arch)+1]) #bigger # Add nodes to plot i = 1 for yi, layer in enumerate(arch): for xi in range(layer): pgm.add_node( daft.Node(str(i), "", xi + ((np.max(arch) - layer) / 2) + 1, yi + 1, aspect=asp)) #weird code to center layers #use aspect to shrink or stretch nodes. can maybe get up to 300 visible nodes on a screen using aspect = 10 #The aspect ratio width/height # print i, xi+1, yi +1 i += 1 # Enumerate all edges in Daft's required syntax # (i.e. str((4,7)) represents edge from node 4 to node 7) # all edges where assigned to a number (increasing starting at 1) in the previous step in order to identify them in # this step. this is why we have to use i_buffer and j_buffer. because all matrices start numbering at rows and col at 0. all_edges = [] i_buffer = 0 j_buffer = arch[0] for mi, matrix in enumerate(all_matrices): for i, row in enumerate(matrix): for j, possible_edge in enumerate(row): if possible_edge == 1: all_edges.append((i + i_buffer + 1, j + j_buffer + 1)) i_buffer += arch[mi] #or j_buffer j_buffer += arch[mi + 1] # Add edges to graph for e in all_edges: pgm.add_edge(str(e[0]), str(e[1])) # Display and save image pgm.render()
def graph(self): """This is just an example, not the actual model. """ rc("font", family="serif", size=12) rc("text", usetex=True) # Colors. p_color = {"ec": "#46a546"} s_color = {"ec": "#f89406"} pgm = daft.PGM() n = daft.Node("phi", r"$\phi$", 1, 3, plot_params=s_color) n.va = "baseline" pgm.add_node(n) pgm.add_node("speckle_coeff", r"$z_i$", 2, 3, plot_params=s_color) pgm.add_node("speckle_img", r"$x_i$", 2, 2, plot_params=s_color) pgm.add_node("spec", r"$s$", 4, 3, plot_params=p_color) pgm.add_node("shape", r"$g$", 4, 2, plot_params=p_color) pgm.add_node("planet_pos", r"$\mu_i$", 3, 3, plot_params=p_color) pgm.add_node("planet_img", r"$p_i$", 3, 2, plot_params=p_color) pgm.add_node("pixels", r"$y_i ^j$", 2.5, 1, observed=True) # Edges. pgm.add_edge("phi", "speckle_coeff") pgm.add_edge("speckle_coeff", "speckle_img") pgm.add_edge("speckle_img", "pixels") pgm.add_edge("spec", "planet_img") pgm.add_edge("shape", "planet_img") pgm.add_edge("planet_pos", "planet_img") pgm.add_edge("planet_img", "pixels") # And a plate. pgm.add_plate([1.5, 0.2, 2, 3.2], label=r"exposure $i$", shift=-0.1) pgm.add_plate([2, 0.5, 1, 1], label=r"pixel $j$", shift=-0.1) # Render and save. pgm.render(dpi=120)
def draw(): # Instantiate a PGM. pgm = daft.PGM([3.3, 3.0], origin=[0.3, 0.3], grid_unit=2.6, node_unit=1.3, observed_style="inner") # Model parameters: pgm.add_node(daft.Node("m", r"$m$", 0.8, 2.8)) pgm.add_node(daft.Node("b", r"$b$", 1.8, 2.8)) # Latent variable - intrinsic or true y: pgm.add_node( daft.Node("ytrue", r"$y^{\rm true}_k$", 1.3, 1.4, fixed=True, offset=(10, -25))) # Data - observed y: pgm.add_node(daft.Node("y", r"$y_k$", 2.5, 1.4, observed=True)) # Constants - x and errors: pgm.add_node( daft.Node("sigma", r"$\sigma_k$", 1.9, 0.9, fixed=True, offset=(-3, 0))) pgm.add_node(daft.Node("x", r"$x_k$", 0.8, 1.1, fixed=True)) # Add in the edges. pgm.add_edge("m", "ytrue") pgm.add_edge("x", "ytrue") pgm.add_edge("b", "ytrue") pgm.add_edge("sigma", "y") pgm.add_edge("ytrue", "y") # And a plate for the pixels pgm.add_plate( daft.Plate([0.5, 0.7, 2.7, 1.4], label=r"datapoints $k$", shift=-0.1)) # Render and save. pgm.render() pgm.figure.savefig("straightline_pgm.png", dpi=300) return