Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some updates for efficiency #106

Merged
merged 3 commits into from Apr 30, 2019
Merged

Some updates for efficiency #106

merged 3 commits into from Apr 30, 2019

Conversation

dsfulf
Copy link
Member

@dsfulf dsfulf commented Jan 4, 2019

Updates for streamlining and efficiency.

I've altered some things to reduce the verbosity of the code required to use Daft.

  1. Pass through of parameters when using add_node() and add_plate() to automatically define the class so that the use of the two is matched to add_edge(). Maintains compatibility with existing code by checking if first parameter is the class instead of the first parameter passed to the class.
  2. Fixed Plate() class kwargs -> plot_params.
  3. Added kwarg to set linewidth for Plate() class rectangle object.
  4. Set default face color of bbox to 'None' as opposed to matplotlib default of cyan (meaning it nearly always had to be specified because cyan is likely a terrible choice).
  5. Added parameter to add_plate() and Plate() class to set fontsize.
  6. Added parameter to add_node() and Node() class to set fontsize. This already existed in label_params but was done for consistency with add_plate() and Plate().
  7. Wrapped pgm.render() in new function pgm.show() to add a plt.show() call. pgm.figure.savefig() still works after pgm.show().

Both sets of code below still function properly, but the proposed changes simplify things somewhat.

Example #1 before changes:

#105  Instantiate the PGM.
pgm = daft.PGM([2.3, 2.05], origin=[0.3, 0.3])

# Hierarchical parameters.
pgm.add_node(daft.Node("alpha", r"$\alpha$", 0.5, 2, fixed=True))
pgm.add_node(daft.Node("beta", r"$\beta$", 1.5, 2))

# Latent variable.
pgm.add_node(daft.Node("w", r"$w_n$", 1, 1))

# Data.
pgm.add_node(daft.Node("x", r"$x_n$", 2, 1, observed=True))

# Add in the edges.
pgm.add_edge("alpha", "beta")
pgm.add_edge("beta", "w")
pgm.add_edge("w", "x")
pgm.add_edge("beta", "x")

# And a plate.
pgm.add_plate(daft.Plate([0.5, 0.5, 2, 1], label=r"$n = 1, \cdots, N$",
    shift=-0.1))

# Render and save.
pgm.render()

Example #1 after changes:

# Instantiate the PGM.
pgm = daft.PGM([2.3, 2.05], origin=[0.3, 0.3])

# Hierarchical parameters.
pgm.add_node("alpha", r"$\alpha$", 0.5, 2, fixed=True)
pgm.add_node("beta", r"$\beta$", 1.5, 2,)

# Latent variable.
pgm.add_node("w", r"$w_n$", 1, 1,)

# Data.
pgm.add_node("x", r"$x_n$", 2, 1, observed=True)

# Add in the edges.
pgm.add_edge("alpha", "beta")
pgm.add_edge("beta", "w")
pgm.add_edge("w", "x")
pgm.add_edge("beta", "x")

# And a plate.
pgm.add_plate([0.5, 0.5, 2, 1], label=r"$n = 1, \cdots, N$",
    shift=-0.1,)

# Render and save.
pgm.show()

@davidwhogg
Copy link
Collaborator

@dfm comments?

This was referenced Jan 6, 2019
@dsfulf
Copy link
Member Author

dsfulf commented Jan 7, 2019

I've made some additional updates to automatically determine figure origin and shape.

A daft.PGM() class can be created just by:

pgm = daft.PGM()

@dsfulf
Copy link
Member Author

dsfulf commented Feb 1, 2019

I added some additional options for setting the DPI of the displayed figure, and made a wrapper for plt.savefig() that correct the default margin setting so it does not lop off the top of a figure that has been tightly spaced with the auto-sizing routine.

The DPI does not override the matplotlib backend, and can be set either on the PGM class instantiation, or in pgm.render(), pgm.show(), and the new pgm.savefig().

@davidwhogg
Copy link
Collaborator

Did you update the documentation and examples so that they all still run?

@dsfulf
Copy link
Member Author

dsfulf commented Feb 17, 2019

Yes. There were a couple of corrections to the examples, but nothing related to anything I've changed.

  1. Use of float division rather than integer division in Python 3.* in recursive.py
  2. A string did not have backslashes escaped in thicklines.py

I have not changed any other examples because it is not necessary. They could be updated to reflect that the shape and origin parameters are not required any longer. I have verified that everything looks exactly the same when these are not provided.

There is a minor detail of the "magic number" used to offset X-coord for the fixed=True parameter in PGM.Node that needs to be adjusted when the figure is auto-sized. I am unable to determine why, and suspect it is internal to matplotlib. I've put in a correction for this case and the examples, specifically yike.py that has 3 fixed nodes, all seem to display identically.

@dsfulf
Copy link
Member Author

dsfulf commented Apr 27, 2019

@dfm @davidwhogg Any hurdles to pass to merge this?

@dfm
Copy link
Member

dfm commented Apr 30, 2019

This looks awesome! Thanks.

@dfm dfm merged commit 0763c94 into daft-dev:master Apr 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants