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

Bryanv/11489 example docstrings #11540

Merged
merged 18 commits into from Sep 2, 2021
Merged
24 changes: 12 additions & 12 deletions bokeh/models/annotations.py
Expand Up @@ -206,7 +206,7 @@ def __init__(self, *args, **kwargs) -> None:

visible = Bool(default=True, help="""
Whether the legend item should be displayed. See
:ref:`userguide_plotting_legends_item_visibility` in the user guide.
:ref:`userguide_annotations_legends_item_visibility` in the user guide.
""")

@error(NON_MATCHING_DATA_SOURCES_ON_LEGEND_ITEM_RENDERERS)
Expand All @@ -227,7 +227,7 @@ def _check_field_label_on_data_source(self):
class Legend(Annotation):
''' Render informational legends for a plot.

See :ref:`userguide_plotting_legends` for information on plotting legends.
See :ref:`userguide_annotations_legends` for information on plotting legends.

'''

Expand Down Expand Up @@ -361,7 +361,7 @@ class Legend(Annotation):
class ColorBar(Annotation):
''' Render a color bar based on a color mapper.

See :ref:`userguide_plotting_color_bars` for information on plotting color bars.
See :ref:`userguide_annotations_color_bars` for information on plotting color bars.

'''

Expand Down Expand Up @@ -509,7 +509,7 @@ class ColorBar(Annotation):
class Arrow(DataAnnotation):
''' Render arrows as an annotation.

See :ref:`userguide_plotting_arrows` for information on plotting arrows.
See :ref:`userguide_annotations_arrows` for information on plotting arrows.

'''

Expand Down Expand Up @@ -554,7 +554,7 @@ class Arrow(DataAnnotation):
class BoxAnnotation(Annotation):
''' Render a shaded rectangular region as an annotation.

See :ref:`userguide_plotting_box_annotations` for information on plotting box annotations.
See :ref:`userguide_annotations_box_annotations` for information on plotting box annotations.

'''

Expand Down Expand Up @@ -642,7 +642,7 @@ class BoxAnnotation(Annotation):
class Band(DataAnnotation):
''' Render a filled area band along a dimension.

See :ref:`userguide_plotting_bands` for information on plotting bands.
See :ref:`userguide_annotations_bands` for information on plotting bands.

'''
lower = PropertyUnitsSpec(default=field("lower"), units_enum=SpatialUnits, units_default="data", help="""
Expand Down Expand Up @@ -694,7 +694,7 @@ class Label(TextAnnotation):
appearance of the text, its background, as well as the rectangular bounding
box border.

See :ref:`userguide_plotting_labels` for information on plotting labels.
See :ref:`userguide_annotations_labels` for information on plotting labels.

'''

Expand Down Expand Up @@ -864,7 +864,7 @@ class LabelSet(TextAnnotation): # TODO: DataAnnotation
class PolyAnnotation(Annotation):
''' Render a shaded polygonal region as an annotation.

See :ref:`userguide_plotting_polygon_annotations` for information on
See :ref:`userguide_annotations_polygon_annotations` for information on
plotting polygon annotations.

'''
Expand Down Expand Up @@ -910,7 +910,7 @@ class PolyAnnotation(Annotation):
class Slope(Annotation):
""" Render a sloped line as an annotation.

See :ref:`userguide_plotting_slope` for information on plotting slopes.
See :ref:`userguide_annotations_slope` for information on plotting slopes.

"""

Expand All @@ -929,7 +929,7 @@ class Slope(Annotation):
class Span(Annotation):
""" Render a horizontal or vertical line span.

See :ref:`userguide_plotting_spans` for information on plotting spans.
See :ref:`userguide_annotations_spans` for information on plotting spans.

"""

Expand Down Expand Up @@ -970,7 +970,7 @@ class Span(Annotation):
class Title(TextAnnotation):
''' Render a single title box as an annotation.

See :ref:`userguide_plotting_titles` for information on plotting titles.
See :ref:`userguide_annotations_titles` for information on plotting titles.

'''

Expand Down Expand Up @@ -1076,7 +1076,7 @@ class Tooltip(Annotation):
class Whisker(DataAnnotation):
''' Render a whisker along a dimension.

See :ref:`userguide_plotting_whiskers` for information on plotting whiskers.
See :ref:`userguide_annotations_whiskers` for information on plotting whiskers.

'''

Expand Down
6 changes: 3 additions & 3 deletions bokeh/plotting/_docstring.py
Expand Up @@ -128,7 +128,7 @@ def _docstring_other():

legend_field (str, optional) :
Specify that the glyph should produce multiple legend entries by
:ref:`grouping them in the browser <userguide_plotting_legends_legend_field>`.
:ref:`grouping them in the browser <userguide_annotations_legends_legend_field>`.
The value of this parameter is the name of a column in the data source
that should be used or the grouping.

Expand All @@ -142,7 +142,7 @@ def _docstring_other():

legend_group (str, optional) :
Specify that the glyph should produce multiple legend entries by
:ref:`grouping them in Python <userguide_plotting_legends_legend_group>`.
:ref:`grouping them in Python <userguide_annotations_legends_legend_group>`.
The value of this parameter is the name of a column in the data source
that should be used or the grouping.

Expand All @@ -156,7 +156,7 @@ def _docstring_other():

legend_label (str, optional) :
Specify that the glyph should produce a single
:ref:`basic legend label <userguide_plotting_legends_legend_label>` in
:ref:`basic legend label <userguide_annotations_legends_legend_label>` in
the legend. The legend entry is labeled with the exact text supplied
here.

Expand Down
81 changes: 81 additions & 0 deletions bokeh/sampledata/anscombe.py
@@ -0,0 +1,81 @@
#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors.
# All rights reserved.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------
''' The four data series that comprise `Anscombe's Quartet`_.

This module contains one pandas Dataframe: ``data``.

.. rubric:: ``data``

:bokeh-dataframe:`bokeh.sampledata.anscombe.data`

.. _Anscombe's Quartet: https://en.wikipedia.org/wiki/Anscombe%27s_quartet

'''

#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------
from __future__ import annotations

import logging # isort:skip
log = logging.getLogger(__name__)

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Standard library imports
from io import StringIO

#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------

__all__ = (
'data',
)

CSV = """
Ix, Iy, IIx, IIy, IIIx, IIIy, IVx, IVy
10.0, 8.04, 10.0, 9.14, 10.0, 7.46, 8.0, 6.58
8.0, 6.95, 8.0, 8.14, 8.0, 6.77, 8.0, 5.76
13.0, 7.58, 13.0, 8.74, 13.0, 12.74, 8.0, 7.71
9.0, 8.81, 9.0, 8.77, 9.0, 7.11, 8.0, 8.84
11.0, 8.33, 11.0, 9.26, 11.0, 7.81, 8.0, 8.47
14.0, 9.96, 14.0, 8.10, 14.0, 8.84, 8.0, 7.04
6.0, 7.24, 6.0, 6.13, 6.0, 6.08, 8.0, 5.25
4.0, 4.26, 4.0, 3.10, 4.0, 5.39, 19.0, 12.50
12.0, 10.84, 12.0, 9.13, 12.0, 8.15, 8.0, 5.56
7.0, 4.82, 7.0, 7.26, 7.0, 6.42, 8.0, 7.91
5.0, 5.68, 5.0, 4.74, 5.0, 5.73, 8.0, 6.89
"""

#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------

def _read_data():
'''

'''
from ..util.dependencies import import_required
pd = import_required('pandas', 'anscombe sample data requires Pandas (http://pandas.pydata.org) to be installed')
return pd.read_csv(StringIO(CSV), skiprows=1, skipinitialspace=True, engine='python')

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------

data = _read_data()
88 changes: 88 additions & 0 deletions bokeh/sampledata/antibiotics.py
@@ -0,0 +1,88 @@
#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors.
# All rights reserved.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------
''' A table of `Will Burtin's historical data`_ regarding antibiotic
efficacies.

This module contains one pandas Dataframe: ``data``.

.. rubric:: ``data``

:bokeh-dataframe:`bokeh.sampledata.antibiotics.data`

.. _Will Burtin's historical data: https://medium.com/@harshdev_41068/burtins-legendary-data-on-antibiotics-9b32ecd5943f

'''

#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------
from __future__ import annotations

import logging # isort:skip
log = logging.getLogger(__name__)

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Standard library imports
from io import StringIO

#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------

__all__ = (
'data',
)

CSV = """
bacteria, penicillin, streptomycin, neomycin, gram
Mycobacterium tuberculosis, 800, 5, 2, negative
Salmonella schottmuelleri, 10, 0.8, 0.09, negative
Proteus vulgaris, 3, 0.1, 0.1, negative
Klebsiella pneumoniae, 850, 1.2, 1, negative
Brucella abortus, 1, 2, 0.02, negative
Pseudomonas aeruginosa, 850, 2, 0.4, negative
Escherichia coli, 100, 0.4, 0.1, negative
Salmonella (Eberthella) typhosa, 1, 0.4, 0.008, negative
Aerobacter aerogenes, 870, 1, 1.6, negative
Brucella antracis, 0.001, 0.01, 0.007, positive
Streptococcus fecalis, 1, 1, 0.1, positive
Staphylococcus aureus, 0.03, 0.03, 0.001, positive
Staphylococcus albus, 0.007, 0.1, 0.001, positive
Streptococcus hemolyticus, 0.001, 14, 10, positive
Streptococcus viridans, 0.005, 10, 40, positive
Diplococcus pneumoniae, 0.005, 11, 10, positive
"""


#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------

def _read_data():
'''

'''
from ..util.dependencies import import_required
pd = import_required('pandas', 'antibiotics sample data requires Pandas (http://pandas.pydata.org) to be installed')
return pd.read_csv(StringIO(CSV), skiprows=1, skipinitialspace=True, engine='python')

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------

data = _read_data()
2 changes: 1 addition & 1 deletion bokeh/sampledata/gapminder.py
Expand Up @@ -25,7 +25,7 @@

:bokeh-dataframe:`bokeh.sampledata.gapminder.population`

.. rubric:: ``life_expectancy``
.. rubric:: ``regions``

:bokeh-dataframe:`bokeh.sampledata.gapminder.regions`

Expand Down
8 changes: 4 additions & 4 deletions bokeh/sphinxext/_templates/example_metadata.rst
@@ -1,6 +1,6 @@
.. rubric:: Details

:Sampledata: {{ sampledata }}
:Bokeh APIs: {{ apis }}
:More info: {{ refs }}
:Keywords: {{ keywords }}
{% if sampledata %}:Sampledata: {{ sampledata }}{% endif %}
{% if apis %}:Bokeh APIs: {{ apis }}{% endif %}
{% if refs %}:More info: {{ refs }}{% endif %}
{% if keywords %}:Keywords: {{ keywords }}{% endif %}
57 changes: 47 additions & 10 deletions bokeh/sphinxext/bokeh_example_metadata.py
Expand Up @@ -73,18 +73,19 @@ class BokehExampleMetadataDirective(BokehDirective):
}

def run(self):
defined_key = False
for key in self.option_spec:
if key in self.options:
defined_key = True
if not defined_key:
raise SphinxError("No fields have been defined for example metadata.")
present = self.option_spec.keys() & self.options.keys()
if not present:
raise SphinxError("bokeh-example-metadata requires at least one option to be present.")

extra = self.options.keys() - self.option_spec.keys()
if extra:
raise SphinxError(f"bokeh-example-metadata unknown options given: {extra}.")

rst_text = EXAMPLE_METADATA.render(
sampledata=self.options['sampledata'],
apis=self.options['apis'],
refs=self.options['refs'],
keywords=self.options['keywords']
sampledata=_sampledata(self.options.get("sampledata", None)),
apis=_apis(self.options.get("apis", None)),
refs=self.options.get("refs", "").split("#")[0],
keywords=self.options.get("keywords", "").split("#")[0],
)

return self.parse(rst_text, "<bokeh-example-metadata>")
Expand All @@ -98,6 +99,42 @@ def setup(app):
# Private API
# -----------------------------------------------------------------------------

def _sampledata(mods: str | None) -> str | None:
if mods is None:
return

# options lines might need a flake8 noqa comment for line length, etc
mods = mods.split("#")[0].strip()

mods = (mod.strip() for mod in mods.split(","))

return ", ".join(f":ref:`bokeh.sampledata.{mod} <sampledata_{mod}>`" for mod in mods)

def _apis(apis: str | None) -> str | None:
if apis is None:
return

# options lines might need a flake8 noqa comment for line length, etc
apis = apis.split("#")[0].strip()

results = []

for api in (api.strip() for api in apis.split(",")):
last = api.split(".")[-1]

# handle a few special cases more carefully
if api.startswith("bokeh.models"):
results.append(f":class:`bokeh.models.{last} <{api}>`")
elif "Figure." in api:
results.append(f":meth:`Figure.{last} <{api}>`")
elif "GMap." in api:
results.append(f":meth:`GMap.{last} <{api}>`")

# just use class role as-is for anything else
else:
results.append(f":class:`{api}`")

return ", ".join(results)

# -----------------------------------------------------------------------------
# Code
Expand Down