Search code examples
pythonpython-3.xpython-sphinxgraphviz

Capturing Graphviz figures in sphinx-gallery


I'm generating examples with sphinx-gallery, and would like to embed graphviz outputs automatically, similar to how matplotlib figures are captured.

A screenshot of my current progress is below. Notice the captured Out shows string or byte representations of the figures.

I would like the Out to be an image/svg.


Current result for embedding graphviz outputs in sphinx-gallery. The outputs are xml or raw byte sequences rather than image data.


I've investigated the following:


Update (2020-11-26): Adding a _repr_html_ that wraps the graphviz's _repr_svg_ method seems like the shortest route. I implemented a rough version:

An alternate version of graphviz was used to generate this image. Here the graph is plotted automatically, rather than a string being printed.


Here is the code for what I have tried already:

# File: examples/plot_graphviz_svg.py

"""
==================================================
Capturing the output of Graphviz in Sphinx-Gallery
==================================================

This is a quick demo trying to capture the SVG output
from Graphviz and embed it in a Sphinx Gallery.
"""

import graphviz

dig = graphviz.Digraph('G', filename='hello.gv')
dig.edge('hello', 'world')
dig._repr_svg_()

# %%
# The first output should be above, the next should appear below:

dig2 = graphviz.Digraph('G2', filename="hello2.gv")
dig2.edge('world', 'hello')
dig.pipe()

A minimal sphinx conf.py:

project = 'sphinx-graphviz-svg'
copyright = '2020, Alexander L. Hayes'
author = 'Alexander L. Hayes'
release = '0.0.1'
extensions = [
    'sphinx_gallery.gen_gallery',
]
templates_path = ['_templates']
exclude_patterns = []
html_theme = 'alabaster'
html_static_path = ['_static']

And a minimal index.rst linking to an Example Gallery:

Welcome to sphinx-graphviz-svg's documentation!
===============================================

.. toctree::
   :hidden:
   :maxdepth: 1
   :caption: Example Gallery

   auto_examples/index

Solution

  • I have an open pull request in the graphviz repository here: #121.

    If you're impatient, here is one possibility with a fairly small wrapper:

    class PlotGraphviz:
    
        def __init__(self, dot_string):
            self.dot_string = dot_string
    
        def _repr_html_(self):
            return graphviz.Source(self.dot_string)._repr_svg_()
    

    This will be cleaner assuming the pull request is merged in the future.

    For now:

    # File: examples/plot_graphviz_svg.py
    
    """
    ==================================================
    Capturing the output of Graphviz in Sphinx-Gallery
    ==================================================
    
    This is a quick demo trying to capture the SVG output
    from Graphviz and embed it in a Sphinx Gallery.
    """
    
    import graphviz
    
    class PlotGraphviz:
    
        def __init__(self, dot_string):
            self.dot_string = dot_string
    
        def _repr_html_(self):
            return graphviz.Source(self.dot_string)._repr_svg_()
    
    # %%
    # First example:
    
    dig = graphviz.Digraph()
    dig.edge("hello", "world")
    PlotGraphviz(str(dig))
    
    # %%
    # More info ...
    

    Renders into:


    Image showing the result that solved the problem.