Advanced usage#

This page contains more advanced topics in case you want to understand howto use Sphinx-Gallery more deeply.

Extend your Makefile for Sphinx-Gallery#

This section describes some common extensions to the documentation Makefilethat are useful for Sphinx-Gallery.

Cleaning the gallery files#

Once your gallery is working you might need completely remove all generatedfiles by Sphinx-Gallery to have a clean build. For this we recommend adding thefollowing to your SphinxMakefile:

clean:rm-rf$(BUILDDIR)/*rm-rfauto_examples/

You need to adapt the secondrm command if you have changed thegallery_dirs config variable.

Build the gallery without running any examples#

If you wish to build your gallery without running examples first (e.g., if anexample takes a long time to run), add the following to yourMakefile.

html-noplot:$(SPHINXBUILD)-Dplot_gallery=0-bhtml$(ALLSPHINXOPTS)$(SOURCEDIR)$(BUILDDIR)/html@echo@echo"Build finished. The HTML pages are in$(BUILDDIR)/html."

Know your Gallery files#

The Gallery has been built, now you and all of your project’s userscan already start enjoying it. All the temporary files needed togenerate the gallery (rst files, images, cache objects, etc) arestored where you configured ingallery_dirs. The final files that gointo the HTML version of your documentation have a particularnamespace, to avoid collisions with your own files and images.

Our namespace convention is to prefix everything withsphx_glr andchange path separators with underscores. For example the first imagegenerated by the example ‘plot_0_sin.py’ has the namesphx_glr_plot_0_sin_001.png and its thumbnail issphx_glr_plot_0_sin_thumb.png

You can also include part of a gallery script elsewhere in your documentationusing theliteralinclude directive, in order to limit codeduplication:

..literalinclude:: ../examples/plot_0_sin.py:language: python:start-after: # License: BSD 3 clause:end-before: # To avoid matplotlib

The above directive inserts the following block:

importmatplotlib.pyplotaspltimportnumpyasnpx=np.linspace(0,2*np.pi,100)y=np.sin(x)plt.plot(x,y)plt.xlabel(r"$x$")plt.ylabel(r"$\sin(x)$")

Warning

Using literalinclude is fragile and can break easily when examples arechanged (all the more when line numbers are used instead ofstart-afterandend-before). Use with caution: linking directly to examples isa more robust alternative.

Cross referencing#

You can also cross reference an example using similar naming convention. Forexample if we want to reference the exampleIntroductory example - Plotting sin, we just call its reference:ref:`sphx_glr_auto_examples_plot_0_sin.py`.Note that we have included the path to the example file (relative totheconf.py file) aftersphx_glr_. Path separators are replaced withunderscores.

Understanding warning and error outputs#

Any warnings or errors that occur when executing code blocks in the galleryPython files will be printed in pink during building of the documentation. The.py file path and the line number that the error occurred in will also beprinted. For example, the exampleExample that fails to execute will raise the followingerror:

File"<full_path>/examples/no_output/plot_raise.py",line27,in<module>iaeNameError:name'iae'isnotdefined

Problems in the text (reST) blocks of the gallery Python files will resultin warnings or errors when Sphinx is converting the generated.rst filesto HTML. These will be printed by Sphinx in pink, after code block errors,during building of the documentation. In this case, the.rst file path and.rst file line number will be printed. To fix the problem, you will needto amend the original.py file,not the generated.rst file.To figure out where the problem is, you will need to match the content of the.rst file at the line number printed to the original.py file.

Example.rst warning:

<full_path>/auto_examples/plot_example.rst:19:WARNING:Explicitmarkupendswithoutablankline;unexpectedunindent.

The warning above occurred due to line 19 inplot_example.rst. Theoriginalplot_example.py file will need to be amended to fix it.Sphinx-Gallery only (re)builds new, modified or failed examples, sore-running the documentation build should rebuild just the modified example,allowing for quick iteration.

Write a custom image scraper#

Warning

The API for custom scrapers is currently experimental.

By default, Sphinx-Gallery supports image scraping for Matplotlib(matplotlib_scraper()). If you wish to captureoutput from other python packages, first determine if the object you wish tocapture has a_repr_html_ method. If so, you can use the configurationcapture_repr (Controlling what output is captured) to control the display of the object,without the need to write a custom scraper. This configuration allows captureof the raw html output, in a process similar to other html-based displays suchasjupyter. If the first option does not work,this section describes how to write a custom scraper.

Image scrapers are functions (or callable class instances) that do the followingthings:

  1. Collect a list of images created in the latest execution of code.

  2. Write these images to disk in PNG, JPEG, SVG, GIF, or WebP format (with .png,.jpg, .svg, .gif, or .webp extensions, respectively)

  3. Return reST that embeds these figures in the built documentation.

The function should take the following inputs (in this order):

  1. block - a Sphinx-Gallery.py file is separated into consecutivelines of ‘code’ and reST ‘text’, called ‘blocks’. For eachblock, anamedtuple with (“type”, “content”, “lineno”) items(e.g.('code','print("Helloworld")',5)) is created.

    • ‘label’ is a string that can either be'text' or'code'. In thiscontext, it should only be'code' as this function is only called forcode blocks.

    • ‘content’ is a string containing the actual content of the code block.

    • ‘lineno’ is an integer, indicating the line number that the blockstarts at.

  2. block_vars - dictionary of configuration and runtime variables. Ofinterest for image scrapers is the element'image_path_iterator' whichis an iterable that returns an absolute path to an image file nameadhering to Sphinx-Gallery naming convention. The path directs to thegallery_dirs/images directory (Configure and use Sphinx-Gallery)and the image file name is'sphx_glr_' followed by the name of thesource.py file then a number, which starts at 1 and increases by 1 ateach iteration. The default file format is.'png'. For example:'home/user/Documents/module/auto_examples/images/sphx_glr_plot_mymodule_001.png'.If a different image extension is desired, the scraper is responsible forreplacing the default.png extension. Only supported image extensions(see above) will enable the file to be picked up by Sphinx-Gallery.

  3. gallery_conf - dictionary containing the configuration of Sphinx-Gallery,set undersphinx_gallery_conf indoc/conf.py (Configuration).Of note, theimage_srcset configuration will provideuser specified image resolutions (as floats) and can be used by your custom scraperto enable multi-resolution images.

It should return a string containing the reST for embedding this figure in thedocumentation. Seematplotlib_scraper() for anexample of a scraper function (click on ‘source’ below the function name to seethe source code). Thematplotlib_scraper() usesthe helper functionsphinx_gallery.scrapers.figure_rst() to help generatereST (see below).

This function will be called once for each code block of your examples.Sphinx-Gallery will take care of scaling images for the galleryindex page thumbnails. PNG, JPEG and WebP images are scaled using Pillow, andSVG and GIF images are copied.

Warning

SVG images do not work withlatex build modes, thus will notwork while building a PDF version of your documentation. You maywant to considersphinxcontrib-svg2pdfconverter.

Example 1: a Matplotlib-style scraper#

For example, we will show sample code for a scraper for a hypothetical package.It uses an approach similar to whatsphinx_gallery.scrapers.matplotlib_scraper() does under the hood, whichuse the helper functionsphinx_gallery.scrapers.figure_rst() tocreate the standardized reST. If your package will be used to write an imagefile to disk (e.g., PNG or JPEG), we recommend you use a similar approach:

defmy_module_scraper(block,block_vars,gallery_conf):importmymodule# We use a list to collect references to image namesimage_names=list()# The `image_path_iterator` is created by Sphinx-Gallery, it will yield# a path to a file name that adheres to Sphinx-Gallery naming convention.image_path_iterator=block_vars['image_path_iterator']# Define a list of our already-created figure objects.list_of_my_figures=mymodule.get_figures()# Iterate through figure objects, save to disk, and keep track of paths.forfig,image_pathinzip(list_of_my_figures,image_path_iterator):fig.save_png(image_path)image_names.append(image_path)# Close all references to figures so they aren't used later.mymodule.close('all')# Use the `figure_rst` helper function to generate the reST for this# code block's figures. Alternatively you can define your own reST.returnfigure_rst(image_names,gallery_conf['src_dir'])

This code could be defined either in yourconf.py file, or as a module thatyou import into yourconf.py file (seeImporting callables).The configuration needed to use this scraper would look like:

sphinx_gallery_conf={...'image_scrapers':('matplotlib',"my_module._scraper.my_module_scraper"),}

Where Sphinx-Gallery will parse the string"my_module._scraper.my_module_scraper"to import the callable function.

Example 2: detecting image files on disk#

Here’s another example that assumes that images havealready been written todisk. In this case we won’tgenerate any image files, we’ll only generatethe reST needed to embed them in the documentation. Note that the example scriptswill still need to be executed to scrape the files, but the imagesdon’t need to be produced during the execution.

We assume the function is defined within yourpackage in a module called_scraper. Here is the scraper code:

fromglobimportglobimportshutilimportosfromsphinx_gallery.scrapersimportfigure_rstdefpng_scraper(block,block_vars,gallery_conf):# Find all PNG files in the directory of this example.path_current_example=os.path.dirname(block_vars['src_file'])pngs=sorted(glob(os.path.join(path_current_example,'*.png')))# Iterate through PNGs, copy them to the Sphinx-Gallery output directoryimage_names=list()image_path_iterator=block_vars['image_path_iterator']seen=set()forpnginpngs:ifpngnotinseen:seen|=set(png)this_image_path=image_path_iterator.next()image_names.append(this_image_path)shutil.move(png,this_image_path)# Use the `figure_rst` helper function to generate reST for image filesreturnfigure_rst(image_names,gallery_conf['src_dir'])

Then, in ourconf.py file, we include the following code:

sphinx_gallery_conf={...'image_scrapers':('matplotlib','my_module._scraper.png_scraper'),}

Example 3: matplotlib with SVG format#

Thesphinx_gallery.scrapers.matplotlib_scraper() supports**kwargsto pass tomatplotlib.figure.Figure.savefig(), one of which is theformat argument. SeeWrite a custom image scraper for supported formats.To use SVG you can define the following function and ensure it isimportable:

defmatplotlib_svg_scraper(*args,**kwargs):returnmatplotlib_scraper(*args,format='svg',**kwargs)

Then in yourconf.py:

sphinx_gallery_conf={...'image_scrapers':("sphinxext.matplotlib_svg_scraper",),...}

You can also use different formats on a per-image basis, but this requireswriting a customized scraper class or function.

Example 4: Mayavi scraper#

Historically, Sphinx-Gallery supported scraping Mayavi figures as well asmatplotlib figures. However, due to the complexity of maintaining the scraper,support was deprecated in version 0.12.0. To continue using a Mayavi scraping,consider using something like the following:

fromsphinx_gallery.scrapersimportfigure_rstdefmayavi_scraper(self,block,block_vars,gallery_conf):frommayaviimportmlabimage_path_iterator=block_vars['image_path_iterator']image_paths=list()e=mlab.get_engine()forscene,image_pathinzip(e.scenes,image_path_iterator):try:mlab.savefig(image_path,figure=scene)exceptException:mlab.close(all=True)raise# make sure the image is not too largescale_image(image_path,image_path,850,999)if'images'ingallery_conf['compress_images']:optipng(image_path,gallery_conf['compress_images_args'])image_paths.append(image_path)mlab.close(all=True)returnfigure_rst(image_paths,gallery_conf['src_dir'])

Integrate custom scrapers with Sphinx-Gallery#

Sphinx-Gallery plans to internally maintain only one scraper: matplotlib.If you have extended or fixed bugs with this scraper, we welcome PRsto improve it!

On the other hand, if you have developed a custom scraper for a differentplotting library that would be useful to the broader community, we encourageyou to get it working with Sphinx-Gallery and then maintain it externally(probably in the package that it scrapes), and then integrate and advertiseit with Sphinx-Gallery. You can:

  1. Contribute it to the list of externally supported scrapers located inResetting modules.

  2. Optional: add a custom hook to your module root to simplify scraper use.Taking PyVista as an example, addingpyvista._get_sg_image_scraper()that returns thecallable scraper to be used by Sphinx-Gallery allowsPyVista users to just use strings as they already can for'matplotlib':

    sphinx_gallery_conf={...'image_scrapers':('pyvista',)}

    Sphinx-Gallery will import the named module (here,pyvista) and use the_get_sg_image_scraper function defined there as a scraper.

Resetting before each example#

Sphinx-Gallery supports ‘resetting’ function(s) that are run before and/or aftereach example script is executed. This is used natively in Sphinx-Gallery to ‘reset’the behavior of the visualization packagesmatplotlib andseaborn(Resetting modules). However, this functionality could be used to reset otherlibraries, modify the resetting behavior for a natively-reset library or runan arbitrary custom function at the start and/or end of each script.

This is done by adding a custom function to the resetting tuple defined inconf.py. The function should take two variables: a dictionary calledgallery_conf (which isyour Sphinx-Gallery configuration) and a string calledfname (which is thefile name of the currently-executed Python script). These generally don’t needto be used in order to perform whatever resetting behavior you want, but mustbe included in the function definition for compatibility reasons.

For example, to reset matplotlib to always use theggplot style, you could do:

defreset_mpl(gallery_conf,fname):frommatplotlibimportstylestyle.use('ggplot')

Any custom functions can be defined (or imported) inconf.py and given tothereset_modules configuration key. To add the function defined above (assumingyou’ve make itimportable):

sphinx_gallery_conf={...'reset_modules':("sphinxext.reset_mpl","seaborn"),}

In the config above"seaborn" refers to the native seaborn resettingfunction (seeResetting modules).

Note

Using resetters such asreset_mpl that deviate from thestandard behavior that users will experience when manually runningexamples themselves is discouraged due to the inconsistencythat results between the rendered examples and local outputs.

If the custom function needs to be aware of whether it is being run before orafter an example, a function signature with three parameters can be used, wherethe third parameter is required to be namedwhen:

defreset_mpl(gallery_conf,fname,when):importmatplotlibasmplmpl.rcParams['lines.linewidth']=2ifwhen=='after'andfname=='dashed_lines':mpl.rcParams['lines.linestyle']='-'

The value passed intowhen can be'before' or'after'.Ifreset_modules_order in theconfigurationis set to'before' or'after',when will always be the same valueas whatreset_modules_order is set to.This function signature is only useful when used in conjunction withreset_modules_order set to'both'.

Altering Sphinx-Gallery CSS#

The Sphinx-Gallery.css files that control the appearance of your examplegallery can be foundhere.These default.css files are added to your build. Specifically, they arecopied into_build/html/_static/ of yourgallery_dir.

You can add your own custom.css files by using theSphinx configurationhtml_static_path.For example, list any path(s) that contain your custom static files, using thehtml_static_path configuration, in yourconf.py file:

html_static_path=['_static']# Custom CSS paths should either relative to html_static_path# or fully qualified paths (eg. https://...)html_css_files=['my_custom.css','other_change.css']

The default Sphinx-Gallery.css files are copied to your buildafterfiles in yourhtml_static_path config. This means that files in yourhtml_static_path that are named the same as Sphinx-Gallery.css fileswill be over-written. You can easily avoid this as all Sphinx-Gallery.cssfiles are prepended with ‘sg_’ (e.g., ‘sg_gallery.css’). More details onthis can be found inPR #845.

Custom css can be used for example to alter the appearance ofcode links andthumbnail size.

Hide the download buttons in the example headers#

div.sphx-glr-download-link-note{display:none;}

Disable thumbnail text on hover#

.sphx-glr-thumbcontainer[tooltip]:hover::before,.sphx-glr-thumbcontainer[tooltip]:hover::after{display:none;}

Using (only) Sphinx-Gallery styles#

If you just want to make use of sphinx-Gallery CSS files, instead of usingthesphinx_gallery.gen_gallery extension, you can use inconf.py:

extensions=['sphinx_gallery.load_style']

This will only cause thegallery.css file to be added to your build.

Using Sphinx-Gallery sidebar components#

Sphinx-Gallery provides two built-in components (which are essentiallySphinx templates):sg_download_links andsg_launcher_links. They are primarily designed for use insecondary sidebarsofpydata-sphinx-theme, but also work with any other configuration that usestemplates, e.g.,html_sidebars.

  • sg_download_links: Displays the download links of source code, Jupyter notebook,and the zip of them for an example.

  • sg_launcher_links: Displays the launcher links for JupyterLite and Binder for anexample.

Note that it is safe to use these components on any page, even if the page is not aSphinx-Gallery example page. The components work by grabbing specific Sphinx-Galleryclasses from the page, hence for non-Sphinx-Gallery pages, the components will simplynot render anything.

Using these components does not mean that the original download and launcher links willbe removed from the page. In fact, they cannot be removed as otherwise the componentscannot grab the necessary information. To visually remove the original links in favorof the components, one can usedisplay:none in CSS to hide them. The relevantclasses are:

.sphx-glr-download-link-note,/* Download link note in header */.binder-badge,/* Binder launch badge in footer */.lite-badge,/* Lite launch badge in footer */.sphx-glr-download-jupyter,/* Download Jupyter notebook link in footer */.sphx-glr-download-python,/* Download Python script link in footer */.sphx-glr-download-zip/* Download zipped link in footer */{display:none;}

Example#

Here we will show an example of how to use these components in the secondary sidebar ofpydata-sphinx-theme. Navigate aroundBasics Gallery with Matplotlib for an example of whatthe sidebar would look like.

Configure the components to be used in the secondary sidebar:

html_theme_options={..."secondary_sidebar_items":["page-toc","sg_download_links","sg_launcher_links"],}

Add the CSS to hide the original download and launcher links (suppose that the CSS isplaced in_static/hide_links.css):

html_static_path=["_static"]defsetup(app):# ...app.add_css_file("hide_links.css")

The above will include the CSS in all pages. If one wants to add the CSS only forcertain pages, one can alternatively do the following (only add to pages that start withauto_examples/):

html_static_path=["_static"]defhide_sg_links(app,pagename,templatename,context,doctree):ifpagename.startswith("auto_examples/"):app.add_css_file("hide_links.css")defsetup(app):# ...app.connect("html-page-context",hide_sg_links)