Repository: DistrictDataLabs/yellowbrick

Issue:
Scripts to Regenerate Tutorial and Quickstart Documentation Images
In the documentation, the tutorial and quickstart need a script that can autogenerate the images similar to how they are done in the `doc/api/` section. The code to generate the images is located in the rst files and can be simple extracted and moved into a py file.

These scripts can live right alongside their .rst compatriots. 


Discussion:

Resolving patch:
diff --git a/docs/api/cluster/elbow.py b/docs/api/cluster/elbow.py
deleted file mode 100644
--- a/docs/api/cluster/elbow.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Generate images for the elbow plot documentation.
-"""
-
-# Import necessary modules
-import matplotlib.pyplot as plt
-
-from sklearn.cluster import KMeans
-from sklearn.datasets import make_blobs
-from yellowbrick.cluster import KElbowVisualizer
-
-
-def draw_elbow(path="images/elbow.png"):
-    # Generate synthetic dataset with 8 blobs
-    X, y = make_blobs(
-        centers=8, n_features=12, n_samples=1000,
-        shuffle=True, random_state=42
-    )
-
-    # Create a new figure to draw the clustering visualizer on
-    _, ax = plt.subplots()
-
-    # Instantiate the clustering model and visualizer
-    model = KMeans()
-    visualizer = KElbowVisualizer(model, ax=ax, k=(4,12))
-
-    visualizer.fit(X)                # Fit the data to the visualizer
-    visualizer.poof(outpath=path)    # Draw/show/poof the data
-
-
-def draw_calinski_harabaz(path="images/calinski_harabaz.png"):
-    # Generate synthetic dataset with 8 blobs
-    X, y = make_blobs(
-        centers=8, n_features=12, n_samples=1000,
-        shuffle=True, random_state=42
-    )
-
-    # Create a new figure to draw the clustering visualizer on
-    _, ax = plt.subplots()
-
-    # Instantiate the clustering model and visualizer
-    model = KMeans()
-    visualizer = KElbowVisualizer(
-        model, ax=ax, k=(4,12),
-        metric='calinski_harabaz', timings=False
-    )
-    visualizer.fit(X)                # Fit the data to the visualizer
-    visualizer.poof(outpath=path)    # Draw/show/poof the data
-
-
-if __name__ == '__main__':
-    draw_elbow()
-    draw_calinski_harabaz()
diff --git a/docs/api/features/importances.py b/docs/api/features/importances.py
deleted file mode 100644
--- a/docs/api/features/importances.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import os
-import pandas as pd
-import matplotlib.pyplot as plt
-
-from yellowbrick.features.importances import FeatureImportances
-from sklearn.ensemble import GradientBoostingClassifier
-from sklearn.linear_model import Lasso, LogisticRegression
-from sklearn.datasets import load_iris
-
-
-DATA_DIR = os.path.relpath(os.path.join(
-    os.path.dirname(__file__), "..", "..", "..", "examples", "data"
-))
-
-
-def feature_importances_(outpath):
-    occupancy = pd.read_csv(os.path.join(DATA_DIR, "occupancy", "occupancy.csv"))
-
-    feats = [
-        "temperature", "relative humidity", "light", "C02", "humidity"
-    ]
-
-    X = occupancy[feats]
-    y = occupancy['occupancy'].astype(int)
-
-    fig = plt.figure()
-    ax = fig.add_subplot()
-
-    viz = FeatureImportances(GradientBoostingClassifier(), ax=ax)
-    viz.fit(X, y)
-    viz.poof(outpath=outpath)
-
-
-def coef_(outpath):
-    concrete = pd.read_csv(os.path.join(DATA_DIR, "concrete", "concrete.csv"))
-
-    feats = ['cement','slag','ash','water','splast','coarse','fine','age']
-    X = concrete[feats]
-    y = concrete['strength']
-
-    fig = plt.figure()
-    ax = fig.add_subplot()
-
-    feats = list(map(lambda s: s.title(), feats))
-    viz = FeatureImportances(Lasso(), ax=ax, labels=feats, relative=False)
-    viz.fit(X, y)
-    viz.poof(outpath=outpath)
-
-
-def stacked_coef_(outpath):
-    data = load_iris()
-
-    fig = plt.figure()
-    ax = fig.add_subplot()
-
-    viz = FeatureImportances(LogisticRegression(), ax=ax, stack=True, relative=False)
-    viz.fit(data.data, data.target)
-    viz.poof(outpath=outpath)
-
-
-if __name__ == '__main__':
-    # feature_importances_("images/feature_importances.png")
-    # coef_("images/feature_importances_coef.png")
-    stacked_coef_("images/feature_importances_stacked.png")
\ No newline at end of file
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,41 +1,74 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
+# conf
+# Yellowbrick documentation build config file, created by sphinx-quickstart
 #
-# yellowbrick documentation build configuration file, created by
-# sphinx-quickstart on Tue Jul  5 19:45:43 2016.
+# Created: Tue Jul 05 19:45:43 2016 -0400
+# Copyright (C) 2016-2019 The scikit-yb developers
+# For license information, see LICENSE.txt
 #
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
+# ID: conf.py [] benjamin@bengfort.com $
+
+"""
+Yellowbrick documentation build config file, created by sphinx-quickstart.
+
+This file is executed with the current directory set to its containing dir
+by ``execfile()``, e.g. the working directory will be yellowbrick/docs.
+Ensure that all specified paths relative to the docs directory are made
+absolute by using ``os.path.abspath``.
+
+Note that not all possible configuration values are present in this
+autogenerated file.
+
+All configuration values have a default; values that are commented out
+serve to show the default.
+
+See: https://www.sphinx-doc.org/en/master/usage/configuration.html
+for more details on configuring the documentation build.
+"""
+
+##########################################################################
+## Imports
+##########################################################################
+
+import os
+import sys
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-import os
-import sys
 sys.path.insert(0, os.path.abspath('..'))
 
 # Set the backend of matplotlib to prevent build errors.
 import matplotlib
 matplotlib.use('agg')
 
+# Import yellowbrick information.
 import yellowbrick as yb
 
-# -- General configuration ------------------------------------------------
+##########################################################################
+## General configuration
+##########################################################################
 
 # If your documentation needs a minimal Sphinx version, state it here.
-#
-# needs_sphinx = '1.0'
+# needs_sphinx = '1.8'
+
+# General information about the project.
+project = 'Yellowbrick'
+copyright = '2016-2019, The scikit-yb developers.'
+author = 'The scikit-yb developers'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+
+# The short X.Y version.
+version = yb.get_version(short=True)
+# The full version, including alpha/beta/rc tags.
+release = "v" + yb.get_version(short=False)
 
 # Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
+# extensions coming with Sphinx (named 'sphinx.ext.*') or custom ones.
 extensions = [
     'sphinx.ext.autodoc',
     'sphinx.ext.autosummary',
@@ -45,6 +78,7 @@
     'sphinx.ext.viewcode',
     'sphinx.ext.todo',
     'numpydoc',
+    'matplotlib.sphinxext.plot_directive',
 ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -52,31 +86,15 @@
 
 # The suffix(es) of source filenames.
 # You can specify multiple suffix as a list of string:
-#
 # source_suffix = ['.rst', '.md']
 source_suffix = '.rst'
 
 # The encoding of source files.
-#
 # source_encoding = 'utf-8-sig'
 
 # The master toctree document.
 master_doc = 'index'
 
-# General information about the project.
-project = 'yellowbrick'
-copyright = '2016, District Data Labs'
-author = 'District Data Labs'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = yb.__version__
-# The full version, including alpha/beta/rc tags.
-release = yb.__version__
-
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
 #
@@ -86,11 +104,9 @@
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
-#
 # today = ''
-#
+
 # Else, today_fmt is used as the format for a strftime call.
-#
 # today_fmt = '%B %d, %Y'
 
 # List of patterns, relative to source directory, that match files and
@@ -98,23 +114,18 @@
 # This patterns also effect to html_static_path and html_extra_path
 exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
 
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-#
+# The reST default role (used for this markup: `text`) for all docs.
 # default_role = None
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
-#
 # add_function_parentheses = True
 
 # If true, the current module name will be prepended to all description
 # unit titles (such as .. function::).
-#
 # add_module_names = True
 
 # If true, sectionauthor and moduleauthor directives will be shown in the
 # output. They are ignored by default.
-#
 # show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
@@ -126,11 +137,61 @@
 # If true, keep warnings as "system message" paragraphs in the built documents.
 # keep_warnings = False
 
+##########################################################################
+## Extension Configuration
+##########################################################################
+
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = False
 
+# Auto-plot settings either as extension or (file format, dpi)
+plot_formats = [
+    'png',
+    'pdf',
+    # ('hires.png', 350),
+]
+
+# By default, include the source code generating plots in documentation
+plot_include_source = True
+
+# Whether to show a link to the source in HTML.
+plot_html_show_source_link = True
+
+# Code that should be executed before each plot.
+plot_pre_code = (
+    "import numpy as np\n"
+    "import matplotlib.pyplot as plt\n"
+    "from yellowbrick.datasets import *\n"
+)
+
+# Whether to show links to the files in HTML.
+plot_html_show_formats = True
 
-# -- Options for HTML output ----------------------------------------------
+# A dictionary containing any non-standard rcParams that should be applied before each plot.
+plot_rcparams = {
+    "figure.figsize": (9,6),
+    "figure.dpi": 128,
+}
+
+# Autodoc requires numpy to skip class members otherwise we get an exception:
+# toctree contains reference to nonexisting document
+# See: https://github.com/phn/pytpm/issues/3#issuecomment-12133978
+numpydoc_show_class_members = False
+
+# Locations of objects.inv files for intersphinx extension that auto-links
+# to external api docs.
+intersphinx_mapping = {
+    'python': ('https://docs.python.org/3', None),
+    'matplotlib': ('http://matplotlib.org/', None),
+    'scipy': ('http://docs.scipy.org/doc/scipy/reference', None),
+    'numpy': ('https://docs.scipy.org/doc/numpy/', None),
+    'cycler': ('http://matplotlib.org/cycler/', None),
+    'sklearn': ('http://scikit-learn.org/stable/', None)
+}
+
+##########################################################################
+## Options for HTML output
+##########################################################################
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
@@ -254,7 +315,9 @@ def setup(app):
 # Output file base name for HTML help builder.
 htmlhelp_basename = 'yellowbrickdoc'
 
-# -- Options for LaTeX output ---------------------------------------------
+##########################################################################
+## Options for LaTeX output
+##########################################################################
 
 latex_elements = {
      # The paper size ('letterpaper' or 'a4paper').
@@ -274,12 +337,15 @@ def setup(app):
      # 'figure_align': 'htbp',
 }
 
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-#  author, documentclass [howto, manual, or own class]).
+# Grouping the document tree into LaTeX files. List of tuples.
 latex_documents = [
-    (master_doc, 'yellowbrick.tex', 'yellowbrick Documentation',
-     'District Data Labs', 'manual'),
+    (
+        master_doc, # source start file
+        'yellowbrick.tex', # target name
+        '{} Documentation'.format(project), # title
+        author, # author
+        'manual' # documentclass [howto,manual, or own class]
+    ),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -308,14 +374,20 @@ def setup(app):
 #
 # latex_domain_indices = True
 
-
-# -- Options for manual page output ---------------------------------------
+##########################################################################
+## Options for manual page output
+##########################################################################
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    (master_doc, 'yellowbrick', 'yellowbrick Documentation',
-     [author], 1)
+    (
+        master_doc,
+        project,
+        '{} Documentation'.format(project),
+        [author],
+        1
+    )
 ]
 
 # If true, show URL addresses after external links.
@@ -329,9 +401,15 @@ def setup(app):
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'yellowbrick', 'yellowbrick Documentation',
-     author, 'yellowbrick', 'One line description of project.',
-     'Miscellaneous'),
+    (
+        master_doc,
+        'yellowbrick',
+        '{} Documentation'.format(project),
+        author,
+        'yellowbrick',
+        'machine learning visualization',
+        'scientific visualization',
+    ),
 ]
 
 # Documents to append as an appendix to all manuals.
@@ -348,17 +426,4 @@ def setup(app):
 
 # If true, do not generate a @detailmenu in the "Top" node's menu.
 #
-# texinfo_no_detailmenu = False
-
-# Autodoc requires numpy to skip class members otherwise we get an exception:
-# toctree contains reference to nonexisting document
-# See: https://github.com/phn/pytpm/issues/3#issuecomment-12133978
-numpydoc_show_class_members = False
-
-# Locations of objects.inv files for intersphinx extension that auto links to external api docs.
-intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
-                       'matplotlib': ('http://matplotlib.org/', None),
-                       'scipy': ('http://scipy.github.io/devdocs/', None),
-                       'numpy': ('https://docs.scipy.org/doc/numpy-dev/', None),
-                       'cycler': ('http://matplotlib.org/cycler/', None),
-                       'sklearn': ('http://scikit-learn.org/stable/', None)}
+# texinfo_no_detailmenu = False
\ No newline at end of file


Test patch: