967 lines
33 KiB
Python
967 lines
33 KiB
Python
|
# scikit-learn documentation build configuration file, created by
|
||
|
# sphinx-quickstart on Fri Jan 8 09:13:42 2010.
|
||
|
#
|
||
|
# 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.
|
||
|
|
||
|
import os
|
||
|
import re
|
||
|
import sys
|
||
|
import warnings
|
||
|
from datetime import datetime
|
||
|
from pathlib import Path
|
||
|
|
||
|
from sklearn.externals._packaging.version import parse
|
||
|
from sklearn.utils._testing import turn_warnings_into_errors
|
||
|
|
||
|
# 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.
|
||
|
sys.path.insert(0, os.path.abspath("."))
|
||
|
sys.path.insert(0, os.path.abspath("sphinxext"))
|
||
|
|
||
|
import jinja2
|
||
|
import sphinx_gallery
|
||
|
from github_link import make_linkcode_resolve
|
||
|
from sphinx_gallery.notebook import add_code_cell, add_markdown_cell
|
||
|
from sphinx_gallery.sorting import ExampleTitleSortKey
|
||
|
|
||
|
try:
|
||
|
# Configure plotly to integrate its output into the HTML pages generated by
|
||
|
# sphinx-gallery.
|
||
|
import plotly.io as pio
|
||
|
|
||
|
pio.renderers.default = "sphinx_gallery"
|
||
|
except ImportError:
|
||
|
# Make it possible to render the doc when not running the examples
|
||
|
# that need plotly.
|
||
|
pass
|
||
|
|
||
|
# -- General configuration ---------------------------------------------------
|
||
|
|
||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||
|
extensions = [
|
||
|
"sphinx.ext.autodoc",
|
||
|
"sphinx.ext.autosummary",
|
||
|
"numpydoc",
|
||
|
"sphinx.ext.linkcode",
|
||
|
"sphinx.ext.doctest",
|
||
|
"sphinx.ext.intersphinx",
|
||
|
"sphinx.ext.imgconverter",
|
||
|
"sphinx_gallery.gen_gallery",
|
||
|
"sphinx-prompt",
|
||
|
"sphinx_copybutton",
|
||
|
"sphinxext.opengraph",
|
||
|
"matplotlib.sphinxext.plot_directive",
|
||
|
"sphinxcontrib.sass",
|
||
|
"sphinx_remove_toctrees",
|
||
|
"sphinx_design",
|
||
|
# See sphinxext/
|
||
|
"allow_nan_estimators",
|
||
|
"autoshortsummary",
|
||
|
"doi_role",
|
||
|
"dropdown_anchors",
|
||
|
"move_gallery_links",
|
||
|
"override_pst_pagetoc",
|
||
|
"sphinx_issues",
|
||
|
]
|
||
|
|
||
|
# Specify how to identify the prompt when copying code snippets
|
||
|
copybutton_prompt_text = r">>> |\.\.\. "
|
||
|
copybutton_prompt_is_regexp = True
|
||
|
copybutton_exclude = "style"
|
||
|
|
||
|
try:
|
||
|
import jupyterlite_sphinx # noqa: F401
|
||
|
|
||
|
extensions.append("jupyterlite_sphinx")
|
||
|
with_jupyterlite = True
|
||
|
except ImportError:
|
||
|
# In some cases we don't want to require jupyterlite_sphinx to be installed,
|
||
|
# e.g. the doc-min-dependencies build
|
||
|
warnings.warn(
|
||
|
"jupyterlite_sphinx is not installed, you need to install it "
|
||
|
"if you want JupyterLite links to appear in each example"
|
||
|
)
|
||
|
with_jupyterlite = False
|
||
|
|
||
|
# Produce `plot::` directives for examples that contain `import matplotlib` or
|
||
|
# `from matplotlib import`.
|
||
|
numpydoc_use_plots = True
|
||
|
|
||
|
# Options for the `::plot` directive:
|
||
|
# https://matplotlib.org/stable/api/sphinxext_plot_directive_api.html
|
||
|
plot_formats = ["png"]
|
||
|
plot_include_source = True
|
||
|
plot_html_show_formats = False
|
||
|
plot_html_show_source_link = False
|
||
|
|
||
|
# We do not need the table of class members because `sphinxext/override_pst_pagetoc.py`
|
||
|
# will show them in the secondary sidebar
|
||
|
numpydoc_show_class_members = False
|
||
|
numpydoc_show_inherited_class_members = False
|
||
|
|
||
|
# We want in-page toc of class members instead of a separate page for each entry
|
||
|
numpydoc_class_members_toctree = False
|
||
|
|
||
|
|
||
|
# For maths, use mathjax by default and svg if NO_MATHJAX env variable is set
|
||
|
# (useful for viewing the doc offline)
|
||
|
if os.environ.get("NO_MATHJAX"):
|
||
|
extensions.append("sphinx.ext.imgmath")
|
||
|
imgmath_image_format = "svg"
|
||
|
mathjax_path = ""
|
||
|
else:
|
||
|
extensions.append("sphinx.ext.mathjax")
|
||
|
mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"
|
||
|
|
||
|
# Add any paths that contain templates here, relative to this directory.
|
||
|
templates_path = ["templates"]
|
||
|
|
||
|
# generate autosummary even if no references
|
||
|
autosummary_generate = True
|
||
|
|
||
|
# The suffix of source filenames.
|
||
|
source_suffix = ".rst"
|
||
|
|
||
|
# The encoding of source files.
|
||
|
source_encoding = "utf-8"
|
||
|
|
||
|
# The main toctree document.
|
||
|
root_doc = "index"
|
||
|
|
||
|
# General information about the project.
|
||
|
project = "scikit-learn"
|
||
|
copyright = f"2007 - {datetime.now().year}, scikit-learn developers (BSD License)"
|
||
|
|
||
|
# 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.
|
||
|
import sklearn
|
||
|
|
||
|
parsed_version = parse(sklearn.__version__)
|
||
|
version = ".".join(parsed_version.base_version.split(".")[:2])
|
||
|
# The full version, including alpha/beta/rc tags.
|
||
|
# Removes post from release name
|
||
|
if parsed_version.is_postrelease:
|
||
|
release = parsed_version.base_version
|
||
|
else:
|
||
|
release = sklearn.__version__
|
||
|
|
||
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||
|
# for a list of supported languages.
|
||
|
# language = None
|
||
|
|
||
|
# 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
|
||
|
# directories to ignore when looking for source files.
|
||
|
exclude_patterns = [
|
||
|
"_build",
|
||
|
"templates",
|
||
|
"includes",
|
||
|
"**/sg_execution_times.rst",
|
||
|
]
|
||
|
|
||
|
# The reST default role (used for this markup: `text`) to use for all
|
||
|
# documents.
|
||
|
default_role = "literal"
|
||
|
|
||
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||
|
add_function_parentheses = False
|
||
|
|
||
|
# 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
|
||
|
|
||
|
# A list of ignored prefixes for module index sorting.
|
||
|
# modindex_common_prefix = []
|
||
|
|
||
|
|
||
|
# -- Options for HTML output -------------------------------------------------
|
||
|
|
||
|
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||
|
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||
|
html_theme = "pydata_sphinx_theme"
|
||
|
|
||
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||
|
# further. For a list of options available for each theme, see the
|
||
|
# documentation.
|
||
|
html_theme_options = {
|
||
|
# -- General configuration ------------------------------------------------
|
||
|
"sidebar_includehidden": True,
|
||
|
"use_edit_page_button": True,
|
||
|
"external_links": [],
|
||
|
"icon_links_label": "Icon Links",
|
||
|
"icon_links": [
|
||
|
{
|
||
|
"name": "GitHub",
|
||
|
"url": "https://github.com/scikit-learn/scikit-learn",
|
||
|
"icon": "fa-brands fa-square-github",
|
||
|
"type": "fontawesome",
|
||
|
},
|
||
|
],
|
||
|
"analytics": {
|
||
|
"plausible_analytics_domain": "scikit-learn.org",
|
||
|
"plausible_analytics_url": "https://views.scientific-python.org/js/script.js",
|
||
|
},
|
||
|
# If "prev-next" is included in article_footer_items, then setting show_prev_next
|
||
|
# to True would repeat prev and next links. See
|
||
|
# https://github.com/pydata/pydata-sphinx-theme/blob/b731dc230bc26a3d1d1bb039c56c977a9b3d25d8/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html#L118-L129
|
||
|
"show_prev_next": False,
|
||
|
"search_bar_text": "Search the docs ...",
|
||
|
"navigation_with_keys": False,
|
||
|
"collapse_navigation": False,
|
||
|
"navigation_depth": 2,
|
||
|
"show_nav_level": 1,
|
||
|
"show_toc_level": 1,
|
||
|
"navbar_align": "left",
|
||
|
"header_links_before_dropdown": 5,
|
||
|
"header_dropdown_text": "More",
|
||
|
# The switcher requires a JSON file with the list of documentation versions, which
|
||
|
# is generated by the script `build_tools/circle/list_versions.py` and placed under
|
||
|
# the `js/` static directory; it will then be copied to the `_static` directory in
|
||
|
# the built documentation
|
||
|
"switcher": {
|
||
|
"json_url": "https://scikit-learn.org/dev/_static/versions.json",
|
||
|
"version_match": release,
|
||
|
},
|
||
|
# check_switcher may be set to False if docbuild pipeline fails. See
|
||
|
# https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/version-dropdown.html#configure-switcher-json-url
|
||
|
"check_switcher": True,
|
||
|
"pygments_light_style": "tango",
|
||
|
"pygments_dark_style": "monokai",
|
||
|
"logo": {
|
||
|
"alt_text": "scikit-learn homepage",
|
||
|
"image_relative": "logos/scikit-learn-logo-small.png",
|
||
|
"image_light": "logos/scikit-learn-logo-small.png",
|
||
|
"image_dark": "logos/scikit-learn-logo-small.png",
|
||
|
},
|
||
|
"surface_warnings": True,
|
||
|
# -- Template placement in theme layouts ----------------------------------
|
||
|
"navbar_start": ["navbar-logo"],
|
||
|
# Note that the alignment of navbar_center is controlled by navbar_align
|
||
|
"navbar_center": ["navbar-nav"],
|
||
|
"navbar_end": ["theme-switcher", "navbar-icon-links", "version-switcher"],
|
||
|
# navbar_persistent is persistent right (even when on mobiles)
|
||
|
"navbar_persistent": ["search-button"],
|
||
|
"article_header_start": ["breadcrumbs"],
|
||
|
"article_header_end": [],
|
||
|
"article_footer_items": ["prev-next"],
|
||
|
"content_footer_items": [],
|
||
|
# Use html_sidebars that map page patterns to list of sidebar templates
|
||
|
"primary_sidebar_end": [],
|
||
|
"footer_start": ["copyright"],
|
||
|
"footer_center": [],
|
||
|
"footer_end": [],
|
||
|
# When specified as a dictionary, the keys should follow glob-style patterns, as in
|
||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-exclude_patterns
|
||
|
# In particular, "**" specifies the default for all pages
|
||
|
# Use :html_theme.sidebar_secondary.remove: for file-wide removal
|
||
|
"secondary_sidebar_items": {"**": ["page-toc", "sourcelink"]},
|
||
|
"show_version_warning_banner": True,
|
||
|
"announcement": None,
|
||
|
}
|
||
|
|
||
|
# Add any paths that contain custom themes here, relative to this directory.
|
||
|
# html_theme_path = ["themes"]
|
||
|
|
||
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||
|
# "<project> v<release> documentation".
|
||
|
# html_title = None
|
||
|
|
||
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
||
|
html_short_title = "scikit-learn"
|
||
|
|
||
|
# The name of an image file (within the static path) to use as favicon of the
|
||
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||
|
# pixels large.
|
||
|
html_favicon = "logos/favicon.ico"
|
||
|
|
||
|
# 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 = ["images", "css", "js"]
|
||
|
|
||
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||
|
# using the given strftime format.
|
||
|
# html_last_updated_fmt = '%b %d, %Y'
|
||
|
|
||
|
# Custom sidebar templates, maps document names to template names.
|
||
|
# Workaround for removing the left sidebar on pages without TOC
|
||
|
# A better solution would be to follow the merge of:
|
||
|
# https://github.com/pydata/pydata-sphinx-theme/pull/1682
|
||
|
html_sidebars = {
|
||
|
"install": [],
|
||
|
"getting_started": [],
|
||
|
"glossary": [],
|
||
|
"faq": [],
|
||
|
"support": [],
|
||
|
"related_projects": [],
|
||
|
"roadmap": [],
|
||
|
"governance": [],
|
||
|
"about": [],
|
||
|
}
|
||
|
|
||
|
# Additional templates that should be rendered to pages, maps page names to
|
||
|
# template names.
|
||
|
html_additional_pages = {"index": "index.html"}
|
||
|
|
||
|
# Additional files to copy
|
||
|
# html_extra_path = []
|
||
|
|
||
|
# Additional JS files
|
||
|
html_js_files = [
|
||
|
"scripts/dropdown.js",
|
||
|
"scripts/version-switcher.js",
|
||
|
]
|
||
|
|
||
|
# Compile scss files into css files using sphinxcontrib-sass
|
||
|
sass_src_dir, sass_out_dir = "scss", "css/styles"
|
||
|
sass_targets = {
|
||
|
f"{file.stem}.scss": f"{file.stem}.css"
|
||
|
for file in Path(sass_src_dir).glob("*.scss")
|
||
|
}
|
||
|
|
||
|
# Additional CSS files, should be subset of the values of `sass_targets`
|
||
|
html_css_files = ["styles/colors.css", "styles/custom.css"]
|
||
|
|
||
|
|
||
|
def add_js_css_files(app, pagename, templatename, context, doctree):
|
||
|
"""Load additional JS and CSS files only for certain pages.
|
||
|
|
||
|
Note that `html_js_files` and `html_css_files` are included in all pages and
|
||
|
should be used for the ones that are used by multiple pages. All page-specific
|
||
|
JS and CSS files should be added here instead.
|
||
|
"""
|
||
|
if pagename == "api/index":
|
||
|
# External: jQuery and DataTables
|
||
|
app.add_js_file("https://code.jquery.com/jquery-3.7.0.js")
|
||
|
app.add_js_file("https://cdn.datatables.net/2.0.0/js/dataTables.min.js")
|
||
|
app.add_css_file(
|
||
|
"https://cdn.datatables.net/2.0.0/css/dataTables.dataTables.min.css"
|
||
|
)
|
||
|
# Internal: API search intialization and styling
|
||
|
app.add_js_file("scripts/api-search.js")
|
||
|
app.add_css_file("styles/api-search.css")
|
||
|
elif pagename == "index":
|
||
|
app.add_css_file("styles/index.css")
|
||
|
elif pagename == "install":
|
||
|
app.add_css_file("styles/install.css")
|
||
|
elif pagename.startswith("modules/generated/"):
|
||
|
app.add_css_file("styles/api.css")
|
||
|
|
||
|
|
||
|
# If false, no module index is generated.
|
||
|
html_domain_indices = False
|
||
|
|
||
|
# If false, no index is generated.
|
||
|
html_use_index = False
|
||
|
|
||
|
# If true, the index is split into individual pages for each letter.
|
||
|
# html_split_index = False
|
||
|
|
||
|
# If true, links to the reST sources are added to the pages.
|
||
|
# html_show_sourcelink = True
|
||
|
|
||
|
# If true, an OpenSearch description file will be output, and all pages will
|
||
|
# contain a <link> tag referring to it. The value of this option must be the
|
||
|
# base URL from which the finished HTML is served.
|
||
|
# html_use_opensearch = ''
|
||
|
|
||
|
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||
|
# html_file_suffix = ''
|
||
|
|
||
|
# Output file base name for HTML help builder.
|
||
|
htmlhelp_basename = "scikit-learndoc"
|
||
|
|
||
|
# If true, the reST sources are included in the HTML build as _sources/name.
|
||
|
html_copy_source = True
|
||
|
|
||
|
# Adds variables into templates
|
||
|
html_context = {}
|
||
|
# finds latest release highlights and places it into HTML context for
|
||
|
# index.html
|
||
|
release_highlights_dir = Path("..") / "examples" / "release_highlights"
|
||
|
# Finds the highlight with the latest version number
|
||
|
latest_highlights = sorted(release_highlights_dir.glob("plot_release_highlights_*.py"))[
|
||
|
-1
|
||
|
]
|
||
|
latest_highlights = latest_highlights.with_suffix("").name
|
||
|
html_context["release_highlights"] = (
|
||
|
f"auto_examples/release_highlights/{latest_highlights}"
|
||
|
)
|
||
|
|
||
|
# get version from highlight name assuming highlights have the form
|
||
|
# plot_release_highlights_0_22_0
|
||
|
highlight_version = ".".join(latest_highlights.split("_")[-3:-1])
|
||
|
html_context["release_highlights_version"] = highlight_version
|
||
|
|
||
|
|
||
|
# redirects dictionary maps from old links to new links
|
||
|
redirects = {
|
||
|
"documentation": "index",
|
||
|
"contents": "index",
|
||
|
"preface": "index",
|
||
|
"modules/classes": "api/index",
|
||
|
"auto_examples/feature_selection/plot_permutation_test_for_classification": (
|
||
|
"auto_examples/model_selection/plot_permutation_tests_for_classification"
|
||
|
),
|
||
|
"modules/model_persistence": "model_persistence",
|
||
|
"auto_examples/linear_model/plot_bayesian_ridge": (
|
||
|
"auto_examples/linear_model/plot_ard"
|
||
|
),
|
||
|
"auto_examples/model_selection/grid_search_text_feature_extraction.py": (
|
||
|
"auto_examples/model_selection/plot_grid_search_text_feature_extraction.py"
|
||
|
),
|
||
|
"auto_examples/miscellaneous/plot_changed_only_pprint_parameter": (
|
||
|
"auto_examples/miscellaneous/plot_estimator_representation"
|
||
|
),
|
||
|
"auto_examples/decomposition/plot_beta_divergence": (
|
||
|
"auto_examples/applications/plot_topics_extraction_with_nmf_lda"
|
||
|
),
|
||
|
"auto_examples/svm/plot_svm_nonlinear": "auto_examples/svm/plot_svm_kernels",
|
||
|
"auto_examples/ensemble/plot_adaboost_hastie_10_2": (
|
||
|
"auto_examples/ensemble/plot_adaboost_multiclass"
|
||
|
),
|
||
|
"auto_examples/decomposition/plot_pca_3d": (
|
||
|
"auto_examples/decomposition/plot_pca_iris"
|
||
|
),
|
||
|
"auto_examples/exercises/plot_cv_digits.py": (
|
||
|
"auto_examples/model_selection/plot_nested_cross_validation_iris.py"
|
||
|
),
|
||
|
"tutorial/machine_learning_map/index.html": "machine_learning_map/index.html",
|
||
|
}
|
||
|
html_context["redirects"] = redirects
|
||
|
for old_link in redirects:
|
||
|
html_additional_pages[old_link] = "redirects.html"
|
||
|
|
||
|
# See https://github.com/scikit-learn/scikit-learn/pull/22550
|
||
|
html_context["is_devrelease"] = parsed_version.is_devrelease
|
||
|
|
||
|
|
||
|
# -- Options for LaTeX output ------------------------------------------------
|
||
|
latex_elements = {
|
||
|
# The paper size ('letterpaper' or 'a4paper').
|
||
|
# 'papersize': 'letterpaper',
|
||
|
# The font size ('10pt', '11pt' or '12pt').
|
||
|
# 'pointsize': '10pt',
|
||
|
# Additional stuff for the LaTeX preamble.
|
||
|
"preamble": r"""
|
||
|
\usepackage{amsmath}\usepackage{amsfonts}\usepackage{bm}
|
||
|
\usepackage{morefloats}\usepackage{enumitem} \setlistdepth{10}
|
||
|
\let\oldhref\href
|
||
|
\renewcommand{\href}[2]{\oldhref{#1}{\hbox{#2}}}
|
||
|
"""
|
||
|
}
|
||
|
|
||
|
# Grouping the document tree into LaTeX files. List of tuples
|
||
|
# (source start file, target name, title, author, documentclass
|
||
|
# [howto/manual]).
|
||
|
latex_documents = [
|
||
|
(
|
||
|
"contents",
|
||
|
"user_guide.tex",
|
||
|
"scikit-learn user guide",
|
||
|
"scikit-learn developers",
|
||
|
"manual",
|
||
|
),
|
||
|
]
|
||
|
|
||
|
# The name of an image file (relative to this directory) to place at the top of
|
||
|
# the title page.
|
||
|
latex_logo = "logos/scikit-learn-logo.png"
|
||
|
|
||
|
# Documents to append as an appendix to all manuals.
|
||
|
# latex_appendices = []
|
||
|
|
||
|
# If false, no module index is generated.
|
||
|
latex_domain_indices = False
|
||
|
|
||
|
trim_doctests_flags = True
|
||
|
|
||
|
# intersphinx configuration
|
||
|
intersphinx_mapping = {
|
||
|
"python": ("https://docs.python.org/{.major}".format(sys.version_info), None),
|
||
|
"numpy": ("https://numpy.org/doc/stable", None),
|
||
|
"scipy": ("https://docs.scipy.org/doc/scipy/", None),
|
||
|
"matplotlib": ("https://matplotlib.org/", None),
|
||
|
"pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None),
|
||
|
"joblib": ("https://joblib.readthedocs.io/en/latest/", None),
|
||
|
"seaborn": ("https://seaborn.pydata.org/", None),
|
||
|
"skops": ("https://skops.readthedocs.io/en/stable/", None),
|
||
|
}
|
||
|
|
||
|
v = parse(release)
|
||
|
if v.release is None:
|
||
|
raise ValueError(
|
||
|
"Ill-formed version: {!r}. Version should follow PEP440".format(version)
|
||
|
)
|
||
|
|
||
|
if v.is_devrelease:
|
||
|
binder_branch = "main"
|
||
|
else:
|
||
|
major, minor = v.release[:2]
|
||
|
binder_branch = "{}.{}.X".format(major, minor)
|
||
|
|
||
|
|
||
|
class SubSectionTitleOrder:
|
||
|
"""Sort example gallery by title of subsection.
|
||
|
|
||
|
Assumes README.txt exists for all subsections and uses the subsection with
|
||
|
dashes, '---', as the adornment.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, src_dir):
|
||
|
self.src_dir = src_dir
|
||
|
self.regex = re.compile(r"^([\w ]+)\n-", re.MULTILINE)
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<%s>" % (self.__class__.__name__,)
|
||
|
|
||
|
def __call__(self, directory):
|
||
|
src_path = os.path.normpath(os.path.join(self.src_dir, directory))
|
||
|
|
||
|
# Forces Release Highlights to the top
|
||
|
if os.path.basename(src_path) == "release_highlights":
|
||
|
return "0"
|
||
|
|
||
|
readme = os.path.join(src_path, "README.txt")
|
||
|
|
||
|
try:
|
||
|
with open(readme, "r") as f:
|
||
|
content = f.read()
|
||
|
except FileNotFoundError:
|
||
|
return directory
|
||
|
|
||
|
title_match = self.regex.search(content)
|
||
|
if title_match is not None:
|
||
|
return title_match.group(1)
|
||
|
return directory
|
||
|
|
||
|
|
||
|
class SKExampleTitleSortKey(ExampleTitleSortKey):
|
||
|
"""Sorts release highlights based on version number."""
|
||
|
|
||
|
def __call__(self, filename):
|
||
|
title = super().__call__(filename)
|
||
|
prefix = "plot_release_highlights_"
|
||
|
|
||
|
# Use title to sort if not a release highlight
|
||
|
if not str(filename).startswith(prefix):
|
||
|
return title
|
||
|
|
||
|
major_minor = filename[len(prefix) :].split("_")[:2]
|
||
|
version_float = float(".".join(major_minor))
|
||
|
|
||
|
# negate to place the newest version highlights first
|
||
|
return -version_float
|
||
|
|
||
|
|
||
|
def notebook_modification_function(notebook_content, notebook_filename):
|
||
|
notebook_content_str = str(notebook_content)
|
||
|
warning_template = "\n".join(
|
||
|
[
|
||
|
"<div class='alert alert-{message_class}'>",
|
||
|
"",
|
||
|
"# JupyterLite warning",
|
||
|
"",
|
||
|
"{message}",
|
||
|
"</div>",
|
||
|
]
|
||
|
)
|
||
|
|
||
|
message_class = "warning"
|
||
|
message = (
|
||
|
"Running the scikit-learn examples in JupyterLite is experimental and you may"
|
||
|
" encounter some unexpected behavior.\n\nThe main difference is that imports"
|
||
|
" will take a lot longer than usual, for example the first `import sklearn` can"
|
||
|
" take roughly 10-20s.\n\nIf you notice problems, feel free to open an"
|
||
|
" [issue](https://github.com/scikit-learn/scikit-learn/issues/new/choose)"
|
||
|
" about it."
|
||
|
)
|
||
|
|
||
|
markdown = warning_template.format(message_class=message_class, message=message)
|
||
|
|
||
|
dummy_notebook_content = {"cells": []}
|
||
|
add_markdown_cell(dummy_notebook_content, markdown)
|
||
|
|
||
|
code_lines = []
|
||
|
|
||
|
if "seaborn" in notebook_content_str:
|
||
|
code_lines.append("%pip install seaborn")
|
||
|
if "plotly.express" in notebook_content_str:
|
||
|
code_lines.append("%pip install plotly")
|
||
|
if "skimage" in notebook_content_str:
|
||
|
code_lines.append("%pip install scikit-image")
|
||
|
if "polars" in notebook_content_str:
|
||
|
code_lines.append("%pip install polars")
|
||
|
if "fetch_" in notebook_content_str:
|
||
|
code_lines.extend(
|
||
|
[
|
||
|
"%pip install pyodide-http",
|
||
|
"import pyodide_http",
|
||
|
"pyodide_http.patch_all()",
|
||
|
]
|
||
|
)
|
||
|
# always import matplotlib and pandas to avoid Pyodide limitation with
|
||
|
# imports inside functions
|
||
|
code_lines.extend(["import matplotlib", "import pandas"])
|
||
|
|
||
|
if code_lines:
|
||
|
code_lines = ["# JupyterLite-specific code"] + code_lines
|
||
|
code = "\n".join(code_lines)
|
||
|
add_code_cell(dummy_notebook_content, code)
|
||
|
|
||
|
notebook_content["cells"] = (
|
||
|
dummy_notebook_content["cells"] + notebook_content["cells"]
|
||
|
)
|
||
|
|
||
|
|
||
|
default_global_config = sklearn.get_config()
|
||
|
|
||
|
|
||
|
def reset_sklearn_config(gallery_conf, fname):
|
||
|
"""Reset sklearn config to default values."""
|
||
|
sklearn.set_config(**default_global_config)
|
||
|
|
||
|
|
||
|
sg_examples_dir = "../examples"
|
||
|
sg_gallery_dir = "auto_examples"
|
||
|
sphinx_gallery_conf = {
|
||
|
"doc_module": "sklearn",
|
||
|
"backreferences_dir": os.path.join("modules", "generated"),
|
||
|
"show_memory": False,
|
||
|
"reference_url": {"sklearn": None},
|
||
|
"examples_dirs": [sg_examples_dir],
|
||
|
"gallery_dirs": [sg_gallery_dir],
|
||
|
"subsection_order": SubSectionTitleOrder(sg_examples_dir),
|
||
|
"within_subsection_order": SKExampleTitleSortKey,
|
||
|
"binder": {
|
||
|
"org": "scikit-learn",
|
||
|
"repo": "scikit-learn",
|
||
|
"binderhub_url": "https://mybinder.org",
|
||
|
"branch": binder_branch,
|
||
|
"dependencies": "./binder/requirements.txt",
|
||
|
"use_jupyter_lab": True,
|
||
|
},
|
||
|
# avoid generating too many cross links
|
||
|
"inspect_global_variables": False,
|
||
|
"remove_config_comments": True,
|
||
|
"plot_gallery": "True",
|
||
|
"recommender": {"enable": True, "n_examples": 4, "min_df": 12},
|
||
|
"reset_modules": ("matplotlib", "seaborn", reset_sklearn_config),
|
||
|
}
|
||
|
if with_jupyterlite:
|
||
|
sphinx_gallery_conf["jupyterlite"] = {
|
||
|
"notebook_modification_function": notebook_modification_function
|
||
|
}
|
||
|
|
||
|
# Secondary sidebar configuration for pages generated by sphinx-gallery
|
||
|
|
||
|
# For the index page of the gallery and each nested section, we hide the secondary
|
||
|
# sidebar by specifying an empty list (no components), because there is no meaningful
|
||
|
# in-page toc for these pages, and they are generated so "sourcelink" is not useful
|
||
|
# either.
|
||
|
|
||
|
# For each example page we keep default ["page-toc", "sourcelink"] specified by the
|
||
|
# "**" key. "page-toc" is wanted for these pages. "sourcelink" is also necessary since
|
||
|
# otherwise the secondary sidebar will degenerate when "page-toc" is empty, and the
|
||
|
# script `sphinxext/move_gallery_links.py` will fail (it assumes the existence of the
|
||
|
# secondary sidebar). The script will remove "sourcelink" in the end.
|
||
|
|
||
|
html_theme_options["secondary_sidebar_items"][f"{sg_gallery_dir}/index"] = []
|
||
|
for sub_sg_dir in (Path(".") / sg_examples_dir).iterdir():
|
||
|
if sub_sg_dir.is_dir():
|
||
|
html_theme_options["secondary_sidebar_items"][
|
||
|
f"{sg_gallery_dir}/{sub_sg_dir.name}/index"
|
||
|
] = []
|
||
|
|
||
|
|
||
|
# The following dictionary contains the information used to create the
|
||
|
# thumbnails for the front page of the scikit-learn home page.
|
||
|
# key: first image in set
|
||
|
# values: (number of plot in set, height of thumbnail)
|
||
|
carousel_thumbs = {"sphx_glr_plot_classifier_comparison_001.png": 600}
|
||
|
|
||
|
|
||
|
# enable experimental module so that experimental estimators can be
|
||
|
# discovered properly by sphinx
|
||
|
from sklearn.experimental import enable_iterative_imputer # noqa
|
||
|
from sklearn.experimental import enable_halving_search_cv # noqa
|
||
|
|
||
|
|
||
|
def make_carousel_thumbs(app, exception):
|
||
|
"""produces the final resized carousel images"""
|
||
|
if exception is not None:
|
||
|
return
|
||
|
print("Preparing carousel images")
|
||
|
|
||
|
image_dir = os.path.join(app.builder.outdir, "_images")
|
||
|
for glr_plot, max_width in carousel_thumbs.items():
|
||
|
image = os.path.join(image_dir, glr_plot)
|
||
|
if os.path.exists(image):
|
||
|
c_thumb = os.path.join(image_dir, glr_plot[:-4] + "_carousel.png")
|
||
|
sphinx_gallery.gen_rst.scale_image(image, c_thumb, max_width, 190)
|
||
|
|
||
|
|
||
|
def filter_search_index(app, exception):
|
||
|
if exception is not None:
|
||
|
return
|
||
|
|
||
|
# searchindex only exist when generating html
|
||
|
if app.builder.name != "html":
|
||
|
return
|
||
|
|
||
|
print("Removing methods from search index")
|
||
|
|
||
|
searchindex_path = os.path.join(app.builder.outdir, "searchindex.js")
|
||
|
with open(searchindex_path, "r") as f:
|
||
|
searchindex_text = f.read()
|
||
|
|
||
|
searchindex_text = re.sub(r"{__init__.+?}", "{}", searchindex_text)
|
||
|
searchindex_text = re.sub(r"{__call__.+?}", "{}", searchindex_text)
|
||
|
|
||
|
with open(searchindex_path, "w") as f:
|
||
|
f.write(searchindex_text)
|
||
|
|
||
|
|
||
|
# Config for sphinx_issues
|
||
|
|
||
|
# we use the issues path for PRs since the issues URL will forward
|
||
|
issues_github_path = "scikit-learn/scikit-learn"
|
||
|
|
||
|
|
||
|
def disable_plot_gallery_for_linkcheck(app):
|
||
|
if app.builder.name == "linkcheck":
|
||
|
sphinx_gallery_conf["plot_gallery"] = "False"
|
||
|
|
||
|
|
||
|
def setup(app):
|
||
|
# do not run the examples when using linkcheck by using a small priority
|
||
|
# (default priority is 500 and sphinx-gallery using builder-inited event too)
|
||
|
app.connect("builder-inited", disable_plot_gallery_for_linkcheck, priority=50)
|
||
|
|
||
|
# triggered just before the HTML for an individual page is created
|
||
|
app.connect("html-page-context", add_js_css_files)
|
||
|
|
||
|
# to hide/show the prompt in code examples
|
||
|
app.connect("build-finished", make_carousel_thumbs)
|
||
|
app.connect("build-finished", filter_search_index)
|
||
|
|
||
|
|
||
|
# The following is used by sphinx.ext.linkcode to provide links to github
|
||
|
linkcode_resolve = make_linkcode_resolve(
|
||
|
"sklearn",
|
||
|
(
|
||
|
"https://github.com/scikit-learn/"
|
||
|
"scikit-learn/blob/{revision}/"
|
||
|
"{package}/{path}#L{lineno}"
|
||
|
),
|
||
|
)
|
||
|
|
||
|
warnings.filterwarnings(
|
||
|
"ignore",
|
||
|
category=UserWarning,
|
||
|
message=(
|
||
|
"Matplotlib is currently using agg, which is a"
|
||
|
" non-GUI backend, so cannot show the figure."
|
||
|
),
|
||
|
)
|
||
|
if os.environ.get("SKLEARN_WARNINGS_AS_ERRORS", "0") != "0":
|
||
|
turn_warnings_into_errors()
|
||
|
|
||
|
# maps functions with a class name that is indistinguishable when case is
|
||
|
# ignore to another filename
|
||
|
autosummary_filename_map = {
|
||
|
"sklearn.cluster.dbscan": "dbscan-function",
|
||
|
"sklearn.covariance.oas": "oas-function",
|
||
|
"sklearn.decomposition.fastica": "fastica-function",
|
||
|
}
|
||
|
|
||
|
|
||
|
# Config for sphinxext.opengraph
|
||
|
|
||
|
ogp_site_url = "https://scikit-learn/stable/"
|
||
|
ogp_image = "https://scikit-learn.org/stable/_static/scikit-learn-logo-small.png"
|
||
|
ogp_use_first_image = True
|
||
|
ogp_site_name = "scikit-learn"
|
||
|
|
||
|
# Config for linkcheck that checks the documentation for broken links
|
||
|
|
||
|
# ignore all links in 'whats_new' to avoid doing many github requests and
|
||
|
# hitting the github rate threshold that makes linkcheck take a lot of time
|
||
|
linkcheck_exclude_documents = [r"whats_new/.*"]
|
||
|
|
||
|
# default timeout to make some sites links fail faster
|
||
|
linkcheck_timeout = 10
|
||
|
|
||
|
# Allow redirects from doi.org
|
||
|
linkcheck_allowed_redirects = {r"https://doi.org/.+": r".*"}
|
||
|
linkcheck_ignore = [
|
||
|
# ignore links to local html files e.g. in image directive :target: field
|
||
|
r"^..?/",
|
||
|
# ignore links to specific pdf pages because linkcheck does not handle them
|
||
|
# ('utf-8' codec can't decode byte error)
|
||
|
r"http://www.utstat.toronto.edu/~rsalakhu/sta4273/notes/Lecture2.pdf#page=.*",
|
||
|
(
|
||
|
"https://www.fordfoundation.org/media/2976/roads-and-bridges"
|
||
|
"-the-unseen-labor-behind-our-digital-infrastructure.pdf#page=.*"
|
||
|
),
|
||
|
# links falsely flagged as broken
|
||
|
(
|
||
|
"https://www.researchgate.net/publication/"
|
||
|
"233096619_A_Dendrite_Method_for_Cluster_Analysis"
|
||
|
),
|
||
|
(
|
||
|
"https://www.researchgate.net/publication/221114584_Random_Fourier"
|
||
|
"_Approximations_for_Skewed_Multiplicative_Histogram_Kernels"
|
||
|
),
|
||
|
(
|
||
|
"https://www.researchgate.net/publication/4974606_"
|
||
|
"Hedonic_housing_prices_and_the_demand_for_clean_air"
|
||
|
),
|
||
|
(
|
||
|
"https://www.researchgate.net/profile/Anh-Huy-Phan/publication/220241471_Fast_"
|
||
|
"Local_Algorithms_for_Large_Scale_Nonnegative_Matrix_and_Tensor_Factorizations"
|
||
|
),
|
||
|
"https://doi.org/10.13140/RG.2.2.35280.02565",
|
||
|
(
|
||
|
"https://www.microsoft.com/en-us/research/uploads/prod/2006/01/"
|
||
|
"Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf"
|
||
|
),
|
||
|
"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-99-87.pdf",
|
||
|
"https://microsoft.com/",
|
||
|
"https://www.jstor.org/stable/2984099",
|
||
|
"https://stat.uw.edu/sites/default/files/files/reports/2000/tr371.pdf",
|
||
|
# Broken links from testimonials
|
||
|
"http://www.bestofmedia.com",
|
||
|
"http://www.data-publica.com/",
|
||
|
"https://livelovely.com",
|
||
|
"https://www.mars.com/global",
|
||
|
"https://www.yhat.com",
|
||
|
# Ignore some dynamically created anchors. See
|
||
|
# https://github.com/sphinx-doc/sphinx/issues/9016 for more details about
|
||
|
# the github example
|
||
|
r"https://github.com/conda-forge/miniforge#miniforge",
|
||
|
r"https://github.com/joblib/threadpoolctl/"
|
||
|
"#setting-the-maximum-size-of-thread-pools",
|
||
|
r"https://stackoverflow.com/questions/5836335/"
|
||
|
"consistently-create-same-random-numpy-array/5837352#comment6712034_5837352",
|
||
|
]
|
||
|
|
||
|
# Config for sphinx-remove-toctrees
|
||
|
|
||
|
remove_from_toctrees = ["metadata_routing.rst"]
|
||
|
|
||
|
# Use a browser-like user agent to avoid some "403 Client Error: Forbidden for
|
||
|
# url" errors. This is taken from the variable navigator.userAgent inside a
|
||
|
# browser console.
|
||
|
user_agent = (
|
||
|
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0"
|
||
|
)
|
||
|
|
||
|
# Use Github token from environment variable to avoid Github rate limits when
|
||
|
# checking Github links
|
||
|
github_token = os.getenv("GITHUB_TOKEN")
|
||
|
|
||
|
if github_token is None:
|
||
|
linkcheck_request_headers = {}
|
||
|
else:
|
||
|
linkcheck_request_headers = {
|
||
|
"https://github.com/": {"Authorization": f"token {github_token}"},
|
||
|
}
|
||
|
|
||
|
|
||
|
# -- Convert .rst.template files to .rst ---------------------------------------
|
||
|
|
||
|
from api_reference import API_REFERENCE, DEPRECATED_API_REFERENCE
|
||
|
|
||
|
from sklearn._min_dependencies import dependent_packages
|
||
|
|
||
|
# If development build, link to local page in the top navbar; otherwise link to the
|
||
|
# development version; see https://github.com/scikit-learn/scikit-learn/pull/22550
|
||
|
if parsed_version.is_devrelease:
|
||
|
development_link = "developers/index"
|
||
|
else:
|
||
|
development_link = "https://scikit-learn.org/dev/developers/index.html"
|
||
|
|
||
|
# Define the templates and target files for conversion
|
||
|
# Each entry is in the format (template name, file name, kwargs for rendering)
|
||
|
rst_templates = [
|
||
|
("index", "index", {"development_link": development_link}),
|
||
|
(
|
||
|
"min_dependency_table",
|
||
|
"min_dependency_table",
|
||
|
{"dependent_packages": dependent_packages},
|
||
|
),
|
||
|
(
|
||
|
"min_dependency_substitutions",
|
||
|
"min_dependency_substitutions",
|
||
|
{"dependent_packages": dependent_packages},
|
||
|
),
|
||
|
(
|
||
|
"api/index",
|
||
|
"api/index",
|
||
|
{
|
||
|
"API_REFERENCE": sorted(API_REFERENCE.items(), key=lambda x: x[0]),
|
||
|
"DEPRECATED_API_REFERENCE": sorted(
|
||
|
DEPRECATED_API_REFERENCE.items(), key=lambda x: x[0], reverse=True
|
||
|
),
|
||
|
},
|
||
|
),
|
||
|
]
|
||
|
|
||
|
# Convert each module API reference page
|
||
|
for module in API_REFERENCE:
|
||
|
rst_templates.append(
|
||
|
(
|
||
|
"api/module",
|
||
|
f"api/{module}",
|
||
|
{"module": module, "module_info": API_REFERENCE[module]},
|
||
|
)
|
||
|
)
|
||
|
|
||
|
# Convert the deprecated API reference page (if there exists any)
|
||
|
if DEPRECATED_API_REFERENCE:
|
||
|
rst_templates.append(
|
||
|
(
|
||
|
"api/deprecated",
|
||
|
"api/deprecated",
|
||
|
{
|
||
|
"DEPRECATED_API_REFERENCE": sorted(
|
||
|
DEPRECATED_API_REFERENCE.items(), key=lambda x: x[0], reverse=True
|
||
|
)
|
||
|
},
|
||
|
)
|
||
|
)
|
||
|
|
||
|
for rst_template_name, rst_target_name, kwargs in rst_templates:
|
||
|
# Read the corresponding template file into jinja2
|
||
|
with (Path(".") / f"{rst_template_name}.rst.template").open(
|
||
|
"r", encoding="utf-8"
|
||
|
) as f:
|
||
|
t = jinja2.Template(f.read())
|
||
|
|
||
|
# Render the template and write to the target
|
||
|
with (Path(".") / f"{rst_target_name}.rst").open("w", encoding="utf-8") as f:
|
||
|
f.write(t.render(**kwargs))
|