From 779d4241ed3f0bfa034728ff34aa9530aa3b98cb Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Tue, 5 Mar 2013 07:31:59 -0500 Subject: [PATCH 1/9] start --- examples/xdstars.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/xdstars.py diff --git a/examples/xdstars.py b/examples/xdstars.py new file mode 100644 index 0000000..d9b3fb3 --- /dev/null +++ b/examples/xdstars.py @@ -0,0 +1,39 @@ +""" +Extreme deconvolution of stars +============================== + +The (very simple) model that transformed SDSS-III. + +""" + +from matplotlib import rc +rc("font", family="serif", size=12) +rc("text", usetex=True) + +import daft + +# Instantiate the PGM. +pgm = daft.PGM([2.3, 2.05], origin=[0.3, 0.3]) + +# Hierarchical parameters. +pgm.add_node(daft.Node("theta", r"$\theta$", 0.5, 2, fixed=True)) +pgm.add_node(daft.Node("sigma", r"$\Sigma$", 1.5, 2)) + +# Latent variable. +pgm.add_node(daft.Node("X", r"$X_n$", 1, 1)) + +# Data. +pgm.add_node(daft.Node("x", r"$x_n$", 2, 1, observed=True)) + +# Add in the edges. +pgm.add_edge("theta", "X") +pgm.add_edge("sigma", "x") +pgm.add_edge("X", "x") + +# And a plate. +pgm.add_plate(daft.Plate([0.5, 0.5, 2, 1], label=r"stars $n$", shift=-0.1)) + +# Render and save. +pgm.render() +pgm.figure.savefig("xdstars.pdf") +pgm.figure.savefig("xdstars.png", dpi=150) From 45d2eae9c0881361c5e1b382e3a9c73aca2e7f12 Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Tue, 5 Mar 2013 07:32:14 -0500 Subject: [PATCH 2/9] not sure what --- examples/weaklensing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/weaklensing.py b/examples/weaklensing.py index 655dbee..bb78be8 100644 --- a/examples/weaklensing.py +++ b/examples/weaklensing.py @@ -14,7 +14,7 @@ from matplotlib import rc rc("font", family="serif", size=12) rc("text", usetex=True) -rc("./weaklensing.tex") +# rc("./weaklensing.tex") import daft From 86db27d879ff80a4dc94edd716d450becb112166 Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Tue, 5 Mar 2013 07:53:32 -0500 Subject: [PATCH 3/9] new layout, better for extending --- daft.py | 8 +++++--- examples/xdstars.py | 12 +++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/daft.py b/daft.py index 81aca5c..091f9f8 100644 --- a/daft.py +++ b/daft.py @@ -186,6 +186,8 @@ def __init__(self, name, content, x, y, scale=1, aspect=None, # Coordinates and dimensions. self.x, self.y = x, y self.scale = scale + if self.fixed: + self.scale = scale / 6. # magic number self.aspect = aspect # Display parameters. @@ -232,11 +234,9 @@ def render(self, ctx): l["ha"] = _pop_multiple(l, "center", "ha", "horizontalalignment") # Deal with ``fixed`` nodes. - scale = self.scale if self.fixed: # MAGIC: These magic numbers should depend on the grid/node units. self.offset[1] += 6 - scale /= 6. l["va"] = "baseline" l.pop("verticalalignment", None) @@ -245,7 +245,7 @@ def render(self, ctx): if p["fc"] == "none": p["fc"] = "k" - diameter = ctx.node_unit * scale + diameter = ctx.node_unit * self.scale if self.aspect is not None: aspect = self.aspect else: @@ -347,6 +347,8 @@ def _get_coords(self, ctx): dist1 = np.sqrt(dy * dy + dx * dx / float(a1 ** 2)) dist2 = np.sqrt(dy * dy + dx * dx / float(a2 ** 2)) + print self.node1, self.node2, self.node1.scale, self.node2.scale + # Compute the fractional effect of the radii of the nodes. alpha1 = 0.5 * ctx.node_unit * self.node1.scale / dist1 alpha2 = 0.5 * ctx.node_unit * self.node2.scale / dist2 diff --git a/examples/xdstars.py b/examples/xdstars.py index d9b3fb3..eea086f 100644 --- a/examples/xdstars.py +++ b/examples/xdstars.py @@ -13,25 +13,27 @@ import daft # Instantiate the PGM. -pgm = daft.PGM([2.3, 2.05], origin=[0.3, 0.3]) +pgm = daft.PGM([2.2, 3.55], origin=[0.4, 0.3]) # Hierarchical parameters. -pgm.add_node(daft.Node("theta", r"$\theta$", 0.5, 2, fixed=True)) -pgm.add_node(daft.Node("sigma", r"$\Sigma$", 1.5, 2)) +pgm.add_node(daft.Node("alpha", r"$\alpha$", 1, 3.5, fixed=True)) +pgm.add_node(daft.Node("theta", r"$\theta$", 1, 2.5)) +pgm.add_node(daft.Node("sigma", r"$\Sigma$", 1, 1)) # Latent variable. -pgm.add_node(daft.Node("X", r"$X_n$", 1, 1)) +pgm.add_node(daft.Node("X", r"$X_n$", 2, 2)) # Data. pgm.add_node(daft.Node("x", r"$x_n$", 2, 1, observed=True)) # Add in the edges. +pgm.add_edge("alpha", "theta") pgm.add_edge("theta", "X") pgm.add_edge("sigma", "x") pgm.add_edge("X", "x") # And a plate. -pgm.add_plate(daft.Plate([0.5, 0.5, 2, 1], label=r"stars $n$", shift=-0.1)) +pgm.add_plate(daft.Plate([1.5, 0.5, 1, 2], label=r"stars $n$", shift=-0.1)) # Render and save. pgm.render() From a9c773940dd28e0ab77d63f3caf81a0a3df19096 Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Tue, 5 Mar 2013 07:58:40 -0500 Subject: [PATCH 4/9] move scale setting --- daft.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/daft.py b/daft.py index 091f9f8..71c432a 100644 --- a/daft.py +++ b/daft.py @@ -347,8 +347,6 @@ def _get_coords(self, ctx): dist1 = np.sqrt(dy * dy + dx * dx / float(a1 ** 2)) dist2 = np.sqrt(dy * dy + dx * dx / float(a2 ** 2)) - print self.node1, self.node2, self.node1.scale, self.node2.scale - # Compute the fractional effect of the radii of the nodes. alpha1 = 0.5 * ctx.node_unit * self.node1.scale / dist1 alpha2 = 0.5 * ctx.node_unit * self.node2.scale / dist2 From 8b623d6a25cdf5b78b0f53f6ab597cd46633a9bb Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Tue, 5 Mar 2013 07:58:55 -0500 Subject: [PATCH 5/9] start, skeleton --- examples/xdqso.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 examples/xdqso.py diff --git a/examples/xdqso.py b/examples/xdqso.py new file mode 100644 index 0000000..3a31b4a --- /dev/null +++ b/examples/xdqso.py @@ -0,0 +1,46 @@ +""" +Extreme deconvolution of stars +============================== + +The (very simple) model that transformed SDSS-III. + +""" + +from matplotlib import rc +rc("font", family="serif", size=12) +rc("text", usetex=True) + +import daft + +# Instantiate the PGM. +pgm = daft.PGM([3.2, 3.55], origin=[-0.6, 0.3]) + +# Hierarchical parameters. +pgm.add_node(daft.Node("alpha", r"$\alpha$", 1, 3.5, fixed=True)) +pgm.add_node(daft.Node("theta", r"$\theta$", 1, 2.5)) +pgm.add_node(daft.Node("sigma", r"$\Sigma$", 1, 1)) + +# Latent variables. +pgm.add_node(daft.Node("q", r"$q_n$", 2, 3)) +pgm.add_node(daft.Node("qt", r"$q_m$", 0, 3)) +pgm.add_node(daft.Node("X", r"$X_n$", 2, 2)) +pgm.add_node(daft.Node("Xt", r"$X_m$", 0, 3)) + +# Data. +pgm.add_node(daft.Node("x", r"$x_n$", 2, 1, observed=True)) +pgm.add_node(daft.Node("x", r"$x_n$", 0, 1, observed=True)) + +# Add in the edges. +pgm.add_edge("alpha", "theta") +pgm.add_edge("theta", "X") +pgm.add_edge("sigma", "x") +pgm.add_edge("X", "x") + +# And plates. +pgm.add_plate(daft.Plate([-0.5, 0.5, 1, 3], label=r"train", shift=-0.1)) +pgm.add_plate(daft.Plate([1.5, 0.5, 1, 3], label=r"test", shift=-0.1)) + +# Render and save. +pgm.render() +pgm.figure.savefig("xdqso.pdf") +pgm.figure.savefig("xdqso.png", dpi=150) From 59f45bb71eb1c7a58e959afe1e6cc31441fa6f7b Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Tue, 5 Mar 2013 07:59:53 -0500 Subject: [PATCH 6/9] start, skeleton --- examples/xdqso.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/xdqso.py b/examples/xdqso.py index 3a31b4a..597d72e 100644 --- a/examples/xdqso.py +++ b/examples/xdqso.py @@ -22,13 +22,13 @@ # Latent variables. pgm.add_node(daft.Node("q", r"$q_n$", 2, 3)) -pgm.add_node(daft.Node("qt", r"$q_m$", 0, 3)) +pgm.add_node(daft.Node("qt", r"$q_m$", 0, 3, observed=True)) pgm.add_node(daft.Node("X", r"$X_n$", 2, 2)) pgm.add_node(daft.Node("Xt", r"$X_m$", 0, 3)) # Data. pgm.add_node(daft.Node("x", r"$x_n$", 2, 1, observed=True)) -pgm.add_node(daft.Node("x", r"$x_n$", 0, 1, observed=True)) +pgm.add_node(daft.Node("xt", r"$x_n$", 0, 1, observed=True)) # Add in the edges. pgm.add_edge("alpha", "theta") From afdbaf00224e520c26d316867d493eecdf853202 Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Tue, 5 Mar 2013 08:07:17 -0500 Subject: [PATCH 7/9] aligning xdstars and xdqso PGMs --- examples/xdqso.py | 17 ++++++++++++----- examples/xdstars.py | 8 ++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/xdqso.py b/examples/xdqso.py index 597d72e..e6e81fc 100644 --- a/examples/xdqso.py +++ b/examples/xdqso.py @@ -21,20 +21,27 @@ pgm.add_node(daft.Node("sigma", r"$\Sigma$", 1, 1)) # Latent variables. -pgm.add_node(daft.Node("q", r"$q_n$", 2, 3)) -pgm.add_node(daft.Node("qt", r"$q_m$", 0, 3, observed=True)) -pgm.add_node(daft.Node("X", r"$X_n$", 2, 2)) -pgm.add_node(daft.Node("Xt", r"$X_m$", 0, 3)) +pgm.add_node(daft.Node("q", r"$q_m$", 2, 3)) +pgm.add_node(daft.Node("X", r"$X_m$", 2, 2)) +pgm.add_node(daft.Node("Xt", r"$X_n$", 0, 2)) # Data. -pgm.add_node(daft.Node("x", r"$x_n$", 2, 1, observed=True)) +pgm.add_node(daft.Node("qt", r"$q_n$", 0, 3, observed=True)) +pgm.add_node(daft.Node("x", r"$x_m$", 2, 1, observed=True)) pgm.add_node(daft.Node("xt", r"$x_n$", 0, 1, observed=True)) # Add in the edges. pgm.add_edge("alpha", "theta") +pgm.add_edge("theta", "q") +pgm.add_edge("theta", "qt") pgm.add_edge("theta", "X") +pgm.add_edge("theta", "Xt") pgm.add_edge("sigma", "x") +pgm.add_edge("sigma", "xt") pgm.add_edge("X", "x") +pgm.add_edge("Xt", "xt") +pgm.add_edge("q", "X") +pgm.add_edge("qt", "Xt") # And plates. pgm.add_plate(daft.Plate([-0.5, 0.5, 1, 3], label=r"train", shift=-0.1)) diff --git a/examples/xdstars.py b/examples/xdstars.py index eea086f..108aadd 100644 --- a/examples/xdstars.py +++ b/examples/xdstars.py @@ -13,7 +13,7 @@ import daft # Instantiate the PGM. -pgm = daft.PGM([2.2, 3.55], origin=[0.4, 0.3]) +pgm = daft.PGM([2.2, 3.55], origin=[-0.6, 0.3]) # Hierarchical parameters. pgm.add_node(daft.Node("alpha", r"$\alpha$", 1, 3.5, fixed=True)) @@ -21,10 +21,10 @@ pgm.add_node(daft.Node("sigma", r"$\Sigma$", 1, 1)) # Latent variable. -pgm.add_node(daft.Node("X", r"$X_n$", 2, 2)) +pgm.add_node(daft.Node("X", r"$X_n$", 0, 2)) # Data. -pgm.add_node(daft.Node("x", r"$x_n$", 2, 1, observed=True)) +pgm.add_node(daft.Node("x", r"$x_n$", 0, 1, observed=True)) # Add in the edges. pgm.add_edge("alpha", "theta") @@ -33,7 +33,7 @@ pgm.add_edge("X", "x") # And a plate. -pgm.add_plate(daft.Plate([1.5, 0.5, 1, 2], label=r"stars $n$", shift=-0.1)) +pgm.add_plate(daft.Plate([-0.5, 0.5, 1, 2], label=r"stars $n$", shift=-0.1)) # Render and save. pgm.render() From 6d0f8b5ec3978e30d121bb3075afaffa21118fa5 Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Wed, 7 Aug 2013 22:21:13 +0200 Subject: [PATCH 8/9] examples --- examples/hayabusa.py | 48 ++++++++++++++++++++++++++++++++++++++++++ examples/stochastic.py | 42 ++++++++++++++++++++++++++++++++++++ examples/xdqso.py | 7 +++--- 3 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 examples/hayabusa.py create mode 100644 examples/stochastic.py diff --git a/examples/hayabusa.py b/examples/hayabusa.py new file mode 100644 index 0000000..b0c8261 --- /dev/null +++ b/examples/hayabusa.py @@ -0,0 +1,48 @@ +""" +Hayabusa +======== + +No comment. + +""" + +from matplotlib import rc +rc("font", family="serif", size=12) +rc("text", usetex=True) +import daft + +pgm = daft.PGM([4.8, 3.2], origin=[-0.4, -0.7]) + +# Hierarchical parameters. +pgm.add_node(daft.Node("theta", r"$\theta$", 0, 1)) +pgm.add_node(daft.Node("Omega", r"$\Omega$", 4, 1)) +pgm.add_node(daft.Node("Sigma", r"$\Sigma$", 0, 0)) + +# spectral measurements +pgm.add_node(daft.Node("a", r"$a_n$", 1, 2, observed=True)) +pgm.add_node(daft.Node("z", r"$z_n$", 2, 2, observed=True)) + +# Latent variables. +pgm.add_node(daft.Node("M", r"$M_n$", 1, 1)) +pgm.add_edge("a", "M") +pgm.add_edge("theta", "M") +pgm.add_node(daft.Node("K", r"$K_n$", 2, 1)) +pgm.add_edge("z", "K") +pgm.add_node(daft.Node("DM", r"$DM_n$", 3, 1)) +pgm.add_edge("z", "DM") +pgm.add_edge("Omega", "DM") + +# Data. +pgm.add_node(daft.Node("m", r"$m_n$", 2, 0, observed=True)) +pgm.add_edge("M", "m") +pgm.add_edge("K", "m") +pgm.add_edge("DM", "m") +pgm.add_edge("Sigma", "m") + +# And a plate. +pgm.add_plate(daft.Plate([0.5, -0.6, 3, 3], label=r"quasars $n$")) + +# Render and save. +pgm.render() +pgm.figure.savefig("hayabusa.pdf") +pgm.figure.savefig("hayabusa.png", dpi=150) diff --git a/examples/stochastic.py b/examples/stochastic.py new file mode 100644 index 0000000..4306f61 --- /dev/null +++ b/examples/stochastic.py @@ -0,0 +1,42 @@ +""" +The Quintessential PGM +====================== + +This is a demonstration of a very common structure found in graphical models. +It has been rendered using Daft's default settings for all the parameters +and it shows off how much beauty is baked in by default. + +""" + +from matplotlib import rc +rc("font", family="serif", size=12) +rc("text", usetex=True) + +import daft + +# Instantiate the PGM. +pgm = daft.PGM([5., 3.1], origin=[-0.5, 0.3]) + +# Hierarchical parameters. +pgm.add_node(daft.Node("alpha", r"$\alpha$", 0.5, 3., fixed=True)) +pgm.add_node(daft.Node("weather", r"stochastic", 0.5, 2., aspect=2.5)) +pgm.add_node(daft.Node("pop", r"population", 2., 3., aspect=2.5)) +pgm.add_node(daft.Node("science", r"target", 2., 2., aspect=2.5)) +pgm.add_node(daft.Node("data", r"data set", 1.5, 1., aspect=2.5)) +pgm.add_node(daft.Node(r"noise", r"\noindent noise\\ model", 3.7, 1., aspect=2.5)) + +# Add in the edges. +pgm.add_edge("alpha", "weather") +pgm.add_edge("weather", "data") +pgm.add_edge("pop", "science") +pgm.add_edge("science", "data") +pgm.add_edge("noise", "data") + +# And a plate. +pgm.add_plate(daft.Plate([-0.3, 0.5, 3.1, 2.], label=r"data sets", + shift=-0.1)) + +# Render and save. +pgm.render() +pgm.figure.savefig("stochastic.pdf") +pgm.figure.savefig("stochastic.png", dpi=150) diff --git a/examples/xdqso.py b/examples/xdqso.py index e6e81fc..7fd6b94 100644 --- a/examples/xdqso.py +++ b/examples/xdqso.py @@ -13,12 +13,13 @@ import daft # Instantiate the PGM. -pgm = daft.PGM([3.2, 3.55], origin=[-0.6, 0.3]) +pgm = daft.PGM([4.00, 3.55], origin=[-0.6, 0.3]) # Hierarchical parameters. pgm.add_node(daft.Node("alpha", r"$\alpha$", 1, 3.5, fixed=True)) pgm.add_node(daft.Node("theta", r"$\theta$", 1, 2.5)) -pgm.add_node(daft.Node("sigma", r"$\Sigma$", 1, 1)) +pgm.add_node(daft.Node("Sigma", r"$\Sigma$", 1, 1)) +pgm.add_node(daft.Node("sigma", r"$\sigma$", 3, 1)) # Latent variables. pgm.add_node(daft.Node("q", r"$q_m$", 2, 3)) @@ -37,7 +38,7 @@ pgm.add_edge("theta", "X") pgm.add_edge("theta", "Xt") pgm.add_edge("sigma", "x") -pgm.add_edge("sigma", "xt") +pgm.add_edge("Sigma", "xt") pgm.add_edge("X", "x") pgm.add_edge("Xt", "xt") pgm.add_edge("q", "X") From 2b6171b96f537dae8884657de3cf555bdc88435c Mon Sep 17 00:00:00 2001 From: "David W. Hogg" Date: Thu, 8 Aug 2013 18:40:19 +0200 Subject: [PATCH 9/9] brewer example; punking Plate to label --- examples/brewer.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 examples/brewer.py diff --git a/examples/brewer.py b/examples/brewer.py new file mode 100644 index 0000000..9e3a0d3 --- /dev/null +++ b/examples/brewer.py @@ -0,0 +1,30 @@ +""" +Brewer's project, sort of +========================= + +This uses a HACK of `Plate` to put a label on the plot. +""" + +from matplotlib import rc +rc("font", family="serif", size=12) +rc("text", usetex=True) + +import daft + +pgm = daft.PGM([5., 2.5], origin=[2.0, 0.0], aspect=2.1) +pgm.add_node(daft.Node("counts", r"$dN/dm$", 6.0, 2.0)) +pgm.add_node(daft.Node("stars", r"stars", 4.5, 2.0,)) +pgm.add_node(daft.Node("pixels", r"pixels", 3.0, 2.0, observed=True)) +pgm.add_node(daft.Node("psf", r"psf", 4.5, 1.0)) +pgm.add_node(daft.Node("noise", r"noise", 3.0, 1.0)) +pgm.add_edge("stars", "pixels") +pgm.add_edge("psf", "pixels") +pgm.add_edge("noise", "pixels") +pgm.add_edge("counts", "stars") +pgm.add_plate(daft.Plate([2.0, 0.0, 7.0, 2.5], + label=r"$p(\mbox{pixels}\,|\,\mbox{stars})\,p(\mbox{stars}\,|\,dN/dm)\,p(dN/dm)$", + label_offset=[30,10], + rect_params={"ec": "none",})) +pgm.render() +pgm.figure.savefig("brewer.pdf") +pgm.figure.savefig("brewer.png", dpi=300)