diff --git a/.gitignore b/.gitignore index ea3c44f759..866e7d4ee8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.sw[op] examples/*.png nb_examples/ +nb_tutorials/ build/* dist/* *.egg-info/ diff --git a/docs/source/Makefile b/docs/source/Makefile index 0969a9c567..2a2f03c65e 100644 --- a/docs/source/Makefile +++ b/docs/source/Makefile @@ -47,6 +47,7 @@ help: @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " serve to launch a server from built html files" clean: rm -rf $(BUILDDIR)/* @@ -190,3 +191,6 @@ pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +serve: html + cd $(BUILDDIR)/html && python -m http.server diff --git a/docs/source/conf.py b/docs/source/conf.py index af8a9c115f..e3f1fec77a 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -143,10 +143,11 @@ html_theme_options = { "navbar_links": [ - ("Quickstart", "intro"), - ("API", "api"), + ("Tutorials", "nb_tutorials/index"), ("Examples", "nb_examples/index"), - ("Learn", "learn"), + ("Books + Videos", "learn"), + ("API", "api"), + ("About PyMC3", "history") ], # "fixed_sidebar": "false", # "description": "Probabilistic Programming in Python: Bayesian Modeling and Probabilistic Machine Learning with Theano" @@ -174,7 +175,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static", "nb_examples/_images"] +html_static_path = ["_static", "nb_tutorials/_images", "nb_examples/_images"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied diff --git a/docs/source/intro.rst b/docs/source/history.rst similarity index 98% rename from docs/source/intro.rst rename to docs/source/history.rst index b61aabb309..1f124cf6c8 100644 --- a/docs/source/intro.rst +++ b/docs/source/history.rst @@ -143,3 +143,9 @@ This example will generate 1000 posterior samples on each of two cores using the The sample is returned as arrays inside of a ``MultiTrace`` object, which is then passed to a plotting function. The resulting graphic shows a forest plot of the random variables in the model, along with a convergence diagnostic (R-hat) that indicates our model has converged. .. image:: ./images/forestplot.png + +See also +======== + +* `Tutorials `__ +* `Examples `__ diff --git a/docs/source/index.rst b/docs/source/index.rst index fd6613c9e5..2fd4a9177a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,9 +16,12 @@ Gaussian processes to fit a regression model.

-

-    X, y = linear_training_data()
 
+.. code-block:: python
+
+    import pymc3 as pm
+
+    X, y = linear_training_data()
     with pm.Model() as linear_model:
         weights = pm.Normal('weights', mu=0, sd=1)
         noise = pm.Gamma('noise', alpha=2, beta=1)
@@ -29,7 +32,10 @@
 
         prior = pm.sample_prior_predictive()
         posterior = pm.sample()
-        posterior_pred = pm.sample_posterior_predictive(posterior)
+ posterior_pred = pm.sample_posterior_predictive(posterior) + +.. raw:: html +
diff --git a/docs/source/learn.rst b/docs/source/learn.rst index a336bcadac..8610b676fa 100644 --- a/docs/source/learn.rst +++ b/docs/source/learn.rst @@ -1,4 +1,4 @@ -.. title:: Learn +.. title:: Learning Resources .. raw:: html diff --git a/docs/source/notebooks/table_of_contents.js b/docs/source/notebooks/table_of_contents_examples.js similarity index 82% rename from docs/source/notebooks/table_of_contents.js rename to docs/source/notebooks/table_of_contents_examples.js index 4ecd0beba5..b358ed313b 100644 --- a/docs/source/notebooks/table_of_contents.js +++ b/docs/source/notebooks/table_of_contents_examples.js @@ -26,15 +26,11 @@ Gallery.contents = { "GP-TProcess": "Gaussian Processes", "GP-slice-sampling": "Gaussian Processes", "GP-smoothing": "Gaussian Processes", - "LKJ": "How-To", "MvGaussianRandomWalk_demo": "Time Series", - "PyMC3_tips_and_heuristic": "How-To", "SMC2_gaussians": "Other", - "api_quickstart": "How-To", "bayes_param_survival_pymc3": "Survival Analysis", "bayesian_neural_network_advi": "Variational Inference", "bayesian_neural_network_with_sgfs": "Stochastic Gradients", - "blackbox_external_likelihood": "How-To", "censored_data": "Survival Analysis", "constant_stochastic_gradient": "Stochastic Gradients", "convolutional_vae_keras_advi": "Variational Inference", @@ -46,26 +42,16 @@ Gallery.contents = { "gaussian-mixture-model-advi": "Mixture Models", "gaussian_mixture_model": "Mixture Models", "gaussian_process": "Gaussian Processes", - "getting_started": "How-To", "hierarchical_partial_pooling": "GLMs", - "howto_debugging": "How-To", - "lasso_block_update": "How-To", "lda-advi-aevb": "Variational Inference", - "live_sample_plots": "How-To", "marginalized_gaussian_mixture_model": "Mixture Models", - "model_averaging": "How-To", "model_comparison": "Diagnostics", "multilevel_modeling": "Applied", "normalizing_flows_overview": "Variational Inference", "posterior_predictive": "Diagnostics", - "profiling": "How-To", "rugby_analytics": "Applied", - "sampler-stats": "How-To", - "sampling_compound_step": "How-To", "sgfs_simple_optimization": "Stochastic Gradients", "stochastic_volatility": "Applied", "survival_analysis": "Survival Analysis", - "updating_priors": "How-To", - "variational_api_quickstart": "Variational Inference", "weibull_aft": "Survival Analysis" } diff --git a/docs/source/notebooks/table_of_contents_tutorials.js b/docs/source/notebooks/table_of_contents_tutorials.js new file mode 100644 index 0000000000..bf607ac5ea --- /dev/null +++ b/docs/source/notebooks/table_of_contents_tutorials.js @@ -0,0 +1,16 @@ +Gallery.contents = { + "api_quickstart": "Basics", + "getting_started": "Basics", + "sampler-stats": "Basics", + "sampling_compound_step": "Basics", + "howto_debugging": "Basics", + "live_sample_plots": "How-To", + "profiling": "How-To", + "updating_priors": "How-To", + "lasso_block_update": "How-To", + "model_averaging": "How-To", + "blackbox_external_likelihood": "How-To", + "LKJ": "How-To", + "variational_api_quickstart": "How-To", + "PyMC3_tips_and_heuristic": "How-To" +} diff --git a/docs/source/semantic_sphinx/layout.html b/docs/source/semantic_sphinx/layout.html index dd99163ece..193db59c68 100644 --- a/docs/source/semantic_sphinx/layout.html +++ b/docs/source/semantic_sphinx/layout.html @@ -5,7 +5,7 @@ '_static/semantic.min.js', ] %} -{% if pagename == 'nb_examples/index' %} +{% if pagename == 'nb_examples/index' or pagename == 'nb_tutorials/index' %} {% set script_files = script_files + [ '_static/gallery.js', ] @@ -18,9 +18,17 @@ +{% if pagename == 'nb_tutorials/index' %} + +{# this is used when loading the gallery index using $.ajax fails, +such as on Chrome for documents on localhost #} + +{% endif %} {% if pagename == 'nb_examples/index' %} {# this is used when loading the gallery index using $.ajax fails, such as on Chrome for documents on localhost #} @@ -62,7 +70,7 @@

Probabilistic Programming in Python

- +
Quickstart
diff --git a/docs/source/semantic_sphinx/static/gallery.js b/docs/source/semantic_sphinx/static/gallery.js index 320797101f..b89177fb68 100644 --- a/docs/source/semantic_sphinx/static/gallery.js +++ b/docs/source/semantic_sphinx/static/gallery.js @@ -70,6 +70,9 @@ var Gallery = { categories["Other"].push(key) } }) + if(categories["Other"].length === 0){ + delete categories["Other"] + } return categories }, diff --git a/docs/source/sphinxext/gallery_generator.py b/docs/source/sphinxext/gallery_generator.py index 49b3eab464..1fc7984089 100644 --- a/docs/source/sphinxext/gallery_generator.py +++ b/docs/source/sphinxext/gallery_generator.py @@ -8,6 +8,7 @@ import os import glob import shutil +import runpy import matplotlib @@ -17,16 +18,16 @@ from matplotlib import image DOC_SRC = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -TABLE_OF_CONTENTS_FILENAME = "table_of_contents.js" +TABLE_OF_CONTENTS_FILENAME = "table_of_contents_{}.js" INDEX_TEMPLATE = """ .. _{sphinx_tag}: -.. title:: example_notebooks +.. title:: {gallery}_notebooks .. raw:: html -

Example Notebooks

+

{Gallery} Notebooks

""" @@ -119,15 +120,30 @@ def gen_previews(self): create_thumbnail(self.png_path) -def main(app): +class TableOfContentsJS(object): + """Container to load table of contents JS file""" + + def load(self, path): + """Creates an attribute ``contents`` by running the JS file as a python + file. + + """ + runpy.run_path(path, {"Gallery": self}) + + +def build_gallery(srcdir, gallery): working_dir = os.getcwd() - os.chdir(app.builder.srcdir) - static_dir = os.path.join(app.builder.srcdir, "_static") - target_dir = os.path.join(app.builder.srcdir, "nb_examples") + os.chdir(srcdir) + static_dir = os.path.join(srcdir, "_static") + target_dir = os.path.join(srcdir, "nb_{}".format(gallery)) image_dir = os.path.join(target_dir, "_images") source_dir = os.path.abspath( - os.path.join(os.path.dirname(os.path.dirname(app.builder.srcdir)), "notebooks") + os.path.join(os.path.dirname(os.path.dirname(srcdir)), "notebooks") ) + table_of_contents_file = os.path.join( + source_dir, TABLE_OF_CONTENTS_FILENAME.format(gallery)) + tocjs = TableOfContentsJS() + tocjs.load(table_of_contents_file) if not os.path.exists(static_dir): os.makedirs(static_dir) @@ -143,16 +159,17 @@ def main(app): # Write individual example files data = {} - for filename in sorted(glob.glob(os.path.join(source_dir, "*.ipynb"))): + for basename in sorted(tocjs.contents): + filename = os.path.join(source_dir, basename + ".ipynb") ex = NotebookGenerator(filename, target_dir) data[ex.stripped_name] = { "title": ex.pagetitle, - "url": os.path.join("/examples", ex.output_html), + "url": os.path.join(os.sep, gallery, ex.output_html), "thumb": os.path.basename(ex.png_path), } - js_file = os.path.join(image_dir, "gallery_contents.js") - with open(os.path.join(source_dir, TABLE_OF_CONTENTS_FILENAME), "r") as toc: + js_file = os.path.join(image_dir, "gallery_{}_contents.js".format(gallery)) + with open(table_of_contents_file, "r") as toc: table_of_contents = toc.read() js_contents = "Gallery.examples = {}\n{}".format( @@ -163,10 +180,19 @@ def main(app): js.write(js_contents) with open(os.path.join(target_dir, "index.rst"), "w") as index: - index.write(INDEX_TEMPLATE.format(sphinx_tag="notebook_gallery")) + index.write(INDEX_TEMPLATE.format( + sphinx_tag="notebook_gallery", + gallery=gallery, + Gallery=gallery.title().rstrip("s") + )) os.chdir(working_dir) +def main(app): + for gallery in ("tutorials", "examples"): + build_gallery(app.builder.srcdir, gallery) + + def setup(app): app.connect("builder-inited", main)