import matplotlib
if not hasattr(matplotlib.RcParams, "_get"):
    matplotlib.RcParams._get = dict.get

Figure Metadata Extension#

A Sphinx extension that provides an interface to add metadata to figures and display the metadata.

This extension enhances Sphinx’s figure directive and the MyST-NB sphinx extension’s glue:figure directive with metadata support for:

  • Author: Image creator/author

  • License: Image license (validated):

  • Date: Creation date (YYYY-MM-DD format)

  • Copyright: Copyright holder

  • Source: Image source

Installation#

To install the Sphinx-Metadata-Figure extension, follow these steps:

Step 1: Install the Package

Install the Sphinx-Metadata-Figure package using pip:

pip install sphinx-metadata-figure

Step 2: Add to requirements.txt

Make sure that the package is included in your project’s requirements.txt to track the dependency:

sphinx-metadata-figure

Step 3: Enable in _config.yml

In your _config.yml file, add the extension to the list of Sphinx extra extensions:

sphinx: 
    extra_extensions:
        - sphinx_metadata_figure

Configuration#

This extension can be configured via the _config.yml file in your JupyterBook project (or similarly in conf.py for standard Sphinx projects).

The default configuration options are as follows:

sphinx:
  config:
    metadata_figure_settings:
      style: 
        placement: hide
        show: author,license,date,copyright,source
        admonition_title: Attribution
        admonition_class: attribution
      license:
        link_license: true
        strict_check: false
        summaries: false
        individual: false
        substitute_missing: false
        default_license: CC BY
      author:
        substitute_missing: false
        default_author: config
      date:
        substitute_missing: false
        default_date: today
      copyright:
        substitute_missing: false
        default_copyright: authoryear
      source:
        warn_missing: false
      bib:
        extract_metadata: true

Each of the level 1 keys in metadata_figure_settings must be a dictionary of key-value pairs. Each level 1 ley will be discussed next, including the options.

Style#

The style key contains options for how the metadata is displayed.

  • placement: Where to place the metadata. Options are

    • caption: as text on a new line in the figure caption. If no figure caption is provided by the user, the metadata will still be added as a caption without introducing figure numbering.

    • admonition: in an admonition box below the figure caption.

    • margin: in an admonition in the margin next to the figure.

    • hide: The metadata is not added to the output, but is verified.

  • show: A comma-separated list of which metadata fields to show. Options that can be included are

    • author

    • license

    • date

    • copyright

    • source

  • admonition_title: (English) title of the admonition box (if placement is admonition or margin). Will be translated if translations are available.

  • admonition_class: CSS class to apply to the admonition box.

The last two options are only relevant if placement is set to admonition or margin.

License#

The license key contains options for how to handle license metadata.

  • link_license: If true, the license name will be a hyperlink to the license text (if known).

  • strict_check: If true, an error will be generated for the first figure without license information or with an invalid license type.

  • summaries: If true, a short summary of all figures without a license or with an invalid license type will be shown during the build.

  • individual: If true, each figure with missing or invalid license information will generate a separate warning. Value is irrelevant if strict_check is true.

  • substitute_missing: If true, figures without license information will use the default_license value. No warning will be generated if this is set to true.

  • default_license: The default license to use if substitute_missing is true.

  • a full list of the valid license types is available in the TeachBooks manual.

Author#

The author key contains options for how to handle author metadata.

  • substitute_missing: If true, figures without author information will use a value based on the default_author option.

  • default_author: The default author to use if substitute_missing is true. Options are:

    • config: Use the author value from the Sphinx configuration.

    • Any other string value will be used as the default author.

Date#

The date key contains options for how to handle date metadata.

  • substitute_missing: If true, figures without date information will use a value based on the default_date option.

  • default_date: The default date to use if substitute_missing is true. Options are:

    • today: Use date at which the build is performed.

    • Any other string value in YYYY-MM-DD format will be used as the default date.

Source#

The source key contains options for how to handle source metadata.

  • warn_missing: If true, a warning will be generated for each figure without source information.

Bib#

The bib key contains options for BibTeX entry support. This allows you to extract figure metadata from existing BibTeX entries.

Configuration options:

  • extract_metadata: If true, metadata will be extracted from existing BibTeX entries when the :bib: option references a valid key. Default: true.

Usage#

The figure directive and the MyST-NB sphinx extension’s glue:figure directive are extended with the following options to add metadata:

  • author:

    • Optionally specify the author/creator of the image.

  • license:

    • Specify the license type of the image. Must be one of the valid license types.

  • date:

    • Optionally specify the creation date of the image.

    • This value can be:

      • a date in YYYY-MM-DD format

      • today, which will result in using the date at which the build is performed.

  • copyright:

    • Optionally specify a text with copyright information for the image.

  • source:

    • Optionally specify the source of the image.

    • This value can be:

      • a URL (starting with “http” or “https”)

      • a textual source description

      • a MarkDown link

      • document, which will result in inserting a MarkDown link of the form [Source code](url_to_parent_document_that_contains_the_figure_directive).

  • placement:

    • Optionally override the global placement setting for this figure only.

    • Options are caption, admonition, margin or hide.

  • show:

    • Optionally override the global show setting for this figure only.

    • Comma-separated list of which metadata fields to show.

    • Options are any combination of author, license, date, copyright and source.

  • admonition_title:

    • Optionally override the global admonition_title setting for this figure only.

    • Only relevant if placement is admonition or margin.

  • admonition_class:

    • Optionally override the global admonition_class setting for this figure only.

    • Only relevant if placement is admonition or margin.

  • bib:

    • Optionally specify a BibTeX key for this figure.

    • When specified with an existing key in your .bib files, metadata (author, date, source, license) will be extracted from the BibTeX entry using the following mapping:

      Metadata Field

      Primary BibTeX Source

      Fallback BibTeX source

      Notes

      author

      author field

      Used as-is

      date

      date field

      year field

      If only year exists, converted to YYYY-01-01 format

      source

      url field

      howpublished field

      If howpublished contains \url{...}, extracts the URL; otherwise uses full value if url not present

      license

      note field

      Only extracted if formatted as license: ... (case-insensitive); the text after the prefix is used

      copyright

      copyright field

      Used as-is

    • Fields that cannot be extracted are simply omitted from metadata (no defaults applied at extraction time)

    • Explicit metadata options (:author:, :license:, etc.) take precedence over extracted bib metadata.

    • The BibTeX entry is also automatically added to the document bibliography using a cite:empty role (when the BibTeX key exists).

Setting Page-Level Defaults#

You can set default metadata values for all figures on a specific page using the default-metadata-page directive. This provides a middle layer between global configuration and per-figure settings.

Syntax#

.. default-metadata-page::
   :author: John Doe
   :license: CC-BY
   :placement: admonition

Or in MyST markdown:

```{default-metadata-page}
:author: John Doe
:license: CC-BY
:placement: admonition
```

Features#

  • Scope: Applies to all figures in the current document only

  • Priority: Page defaults override global config and BibTeX metadata, but are overridden by explicit figure options

  • All options supported: You can set any metadata field or display option at page level

Priority Order#

When determining metadata values, the extension follows this priority chain (highest to lowest):

  1. Explicit figure option (:author: on the figure directive)

  2. Page-level default (from default-metadata-page)

  3. BibTeX metadata (when :bib: references an existing entry)

  4. Global configuration (from _config.yml)

For detailed examples and usage, see the Page-Level Defaults section in the manual.

Examples using default settings#

These examples assume that the config only has the default options except for the placement, summaries, and individual options which are set as follows:

sphinx:
  config:
    metadata_figure_settings:
      style: 
        placement: caption
      license:
        summaries: true
        individual: true

Example 1: Complete Metadata#

Note that the license is given in Indonesian: “Hak cipta dilindungi”, but it is automatically translated to the language set in conf.py/_config.yml.

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata1
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: Hak cipta dilindungi
:source: [TeachBooks Logos and Visuals](https://github.com/TeachBooks/logos_and_visualisations)
:copyright: © TeachBooks 2024

The logo of TeachBooks.
```
../../../_images/TeachBooks_logo.svg

Fig. 113 The logo of TeachBooks.
#

Example 2: Minimal Metadata (only a license)#

Not that the license given has some common issues:

  • The dash in “CC-BY” should be spaces: “CC BY”

  • The version is missing: “CC BY 4.0”

The code automatically corrects these issues.

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata2
:width: 50%
:license: CC-BY

The logo of TeachBooks.
```
../../../_images/TeachBooks_logo.svg

Fig. 114 The logo of TeachBooks.
#

Example 3: Without License (generates a warning)#

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata3
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:source: [TeachBooks Logos and Visuals](https://github.com/TeachBooks/logos_and_visualisations)
:copyright: © TeachBooks 2024

The logo of TeachBooks.
```
../../../_images/TeachBooks_logo.svg

Fig. 115 The logo of TeachBooks.
#

Example 4: Invalid License (generates a warning)#

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata4
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: Unknown
:source: [TeachBooks Logos and Visuals](https://github.com/TeachBooks/logos_and_visualisations)
:copyright: © TeachBooks 2024

The logo of TeachBooks.
```
../../../_images/TeachBooks_logo.svg

Fig. 116 The logo of TeachBooks.
#

Example 5: Placement as an admonition below the caption#

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata5
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: CC BY
:source: [TeachBooks Logos and Visuals](https://github.com/TeachBooks/logos_and_visualisations)
:copyright: © TeachBooks 2024
:placement: admonition

The logo of TeachBooks.
```
../../../_images/TeachBooks_logo.svg

Fig. 117 The logo of TeachBooks.#

Attribution

Author: Veronica Comin | License: CC BY 4.0 | Date: 2024-11-13 | Copyright: © TeachBooks 2024 | Source: TeachBooks Logos and Visuals

Example 6: Placement as an admonition in the margin#

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata6
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: CC BY
:source: [TeachBooks Logos and Visuals](https://github.com/TeachBooks/logos_and_visualisations)
:copyright: © TeachBooks 2024
:placement: margin

The logo of TeachBooks.
```

Attribution

Author: Veronica Comin | License: CC BY 4.0 | Date: 2024-11-13 | Copyright: © TeachBooks 2024 | Source: TeachBooks Logos and Visuals

../../../_images/TeachBooks_logo.svg

Fig. 118 The logo of TeachBooks.#

Example 7: Hidden Metadata#

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata7
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: CC BY
:source: [TeachBooks Logos and Visuals](https://github.com/TeachBooks/logos_and_visualisations)
:copyright: © TeachBooks 2024
:placement: hide

The logo of TeachBooks.
```
../../../_images/TeachBooks_logo.svg

Fig. 119 The logo of TeachBooks.#

Example 8: Placement in caption without a caption provided by the user#

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata8
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: CC BY
:source: document
:copyright: © TeachBooks 2024
:placement: caption

```
../../../_images/TeachBooks_logo.svg

#

Example 9: Source as “document”#

import numpy as np

import matplotlib.pyplot as plt

# Create a simple plot
fig, ax = plt.subplots(figsize=(6, 4))
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

ax.plot(x, y, linewidth=2, color='blue')
ax.set_xlabel('x')
ax.set_ylabel('sin(x)')
ax.set_title('Simple Sine Wave')
ax.grid(True, alpha=0.3)

# Save as SVG
plt.savefig('MANUAL_sine_wave.svg', format='svg', bbox_inches='tight')
```{figure} ./MANUAL_sine_wave.svg
:name: tb_logo_metadata9
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: CC BY
:source: document
:copyright: © TeachBooks 2024
:placement: caption

The logo of TeachBooks.
```
../../../_images/MANUAL_sine_wave.svg

Fig. 120 The logo of TeachBooks.
#

Example 10: Source as “document” using glue#

from myst_nb import glue

import numpy as np

import matplotlib.pyplot as plt

# Create a simple plot
fig, ax = plt.subplots(figsize=(6, 4))
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

ax.plot(x, y, linewidth=2, color='blue')
ax.set_xlabel('x')
ax.set_ylabel('sin(x)')
ax.set_title('Simple Sine Wave')
ax.grid(True, alpha=0.3)

fig = plt.gcf()
glue("MANUAL_sine_wave", fig, display=False)
plt.close();
```{glue:figure} MANUAL_sine_wave
:name: tb_logo_metadata10
:width: 50%
:author: Veronica Comin
:date: 2024-11-13
:license: CC BY
:source: document
:copyright: © TeachBooks 2024
:placement: caption

The logo of TeachBooks.
```
../../../_images/a287429d56c505ad69b0bd615a95f552dc4a2bfff3b79fb12067d1dcfec9d08b.png

Fig. 121 The logo of TeachBooks.
#

Example 11: Metadata with BibTeX extraction#

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata11
:width: 50%
:bib: TeachBooksLogo

The logo of TeachBooks.
```
../../../_images/TeachBooks_logo.svg

Fig. 122 The logo of TeachBooks.
#

The corresponding BibTeX entry in a .bib file would be:

@misc{TeachBooksLogo,
  author = {Veronica Comin},
  title = {The logo of TeachBooks.},
  year = {2024},
  date = {2024-11-13},
  note = {License: CC BY},
  url = {https://github.com/TeachBooks/logos_and_visualisations},
  howpublished = {\url{https://github.com/TeachBooks/logos_and_visualisations}},
  copyright = {© TeachBooks 2024}
}

Example 12: Page-level metadata defaults#

The default-metadata-page directive allows you to set default metadata values for all figures on a page. This reduces repetition when multiple figures share common metadata.

```{default-metadata-page}
:author: Historical Archive
:license: Public Domain
:date: 1920-01-01
:placement: margin
```

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata12a
:width: 40%

Photo 1: Uses all page defaults (author, license, date, placement).
```

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata12b
:width: 40%
:author: Specific Photographer

Photo 2: Overrides author but keeps page default license, date, and placement.
```

```{figure} /images/TeachBooks_logo.svg
:name: tb_logo_metadata12c
:width: 40%
:license: CC BY
:placement: caption

Photo 3: Overrides license and placement, keeps page default author and date.
```

Attribution

Author: Historical Archive | License: Public Domain | Date: 1920-01-01

../../../_images/TeachBooks_logo.svg

Fig. 123 Photo 1: Uses all page defaults (author, license, date, placement).#

Attribution

Author: Specific Photographer | License: Public Domain | Date: 1920-01-01

../../../_images/TeachBooks_logo.svg

Fig. 124 Photo 2: Overrides author but keeps page default license, date, and placement.#

../../../_images/TeachBooks_logo.svg

Fig. 125 Photo 3: Overrides license and placement, keeps page default author and date.
#

Priority order for metadata values:

  1. Explicit figure option (:author: on the figure directive)

  2. Page-level default (from default-metadata-page)

  3. BibTeX metadata (when :bib: references an existing entry)

  4. Global configuration (from _config.yml)

Recognized licenses#

The following licenses are recognized and validated by the Sphinx-Metadata-Figure extension:

License

Long name

Notes

CC0

Creative Commons Zero

CC BY

Creative Commons Attribution

4.0 is assumed and appended to output, (another) version can be appended to indicate specific version explicitly, for example CC BY 3.0. Supported are 1.0, 2.0, 2.5, 3.0 and 4.0.

CC BY-SA

Creative Commons Attribution-ShareAlike

4.0 is assumed and appended to output, (another) version can be appended to indicate specific version explicitly, for example CC BY-SA 3.0. Supported are 1.0, 2.0, 2.5, 3.0 and 4.0.

CC BY-NC

Creative Commons Attribution-NonCommercial

4.0 is assumed and appended to output, (another) version can be appended to indicate specific version explicitly, for example CC BY-NC 3.0. Supported are 1.0, 2.0, 2.5, 3.0 and 4.0.

CC BY-NC-SA

Creative Commons Attribution-NonCommercial-ShareAlike

4.0 is assumed and appended to output, (another) version can be appended to indicate specific version explicitly, for example CC BY-NC-SA 3.0. Supported are 1.0, 2.0, 2.5, 3.0 and 4.0.

CC BY-ND

Creative Commons Attribution-NoDerivatives

4.0 is assumed and appended to output, (another) version can be appended to indicate specific version explicitly, for example CC BY-ND 3.0. Supported are 1.0, 2.0, 2.5, 3.0 and 4.0.

CC BY-NC-ND

Creative Commons Attribution-NonCommercial-NoDerivatives

4.0 is assumed and appended to output, (another) version can be appended to indicate specific version explicitly, for example CC BY-NC-ND 3.0. Supported are 1.0, 2.0, 2.5, 3.0 and 4.0.

Public Domain

Public Domain

Translated to language set in conf.py/_config.yml. License name can also be given in a language other than English. In that case a translation to English is attempted for validation first.

MIT

MIT License

Apache-2.0

Apache License 2.0

GPL-3.0

GNU General Public License v3.0

GPL-2.0

GNU General Public License v2.0

LGPL-2.1

GNU Lesser General Public License v2.1

LGPL-3.0

GNU Lesser General Public License v3.0

AGPL-3.0

GNU Affero General Public License v3.0

BSD-3-Clause

BSD 3-Clause “New” or “Revised” License

BSD-2-Clause

BSD 2-Clause “Simplified” or “FreeBSD” License

Proprietary

Proprietary License

Translated to language set in conf.py/_config.yml. License name can also be given in a language other than English. In that case a translation to English is attempted for validation first.

All Rights Reserved

All Rights Reserved

Translated to language set in conf.py/_config.yml. License name can also be given in a language other than English. In that case a translation to English is attempted for validation first.

Pixabay License

Pixabay License

Translated to language set in conf.py/_config.yml. License name can also be given in a language other than English. In that case a translation to English is attempted for validation first.

Unsplash License

Unsplash License

Translated to language set in conf.py/_config.yml. License name can also be given in a language other than English. In that case a translation to English is attempted for validation first.

Pexels License

Pexels License

Translated to language set in conf.py/_config.yml. License name can also be given in a language other than English. In that case a translation to English is attempted for validation first.

Contribute#

This tool’s repository is stored on GitHub. If you’d like to contribute, you can create a fork and open a pull request on the GitHub repository.