Skip to main content

Generate and render optionally themed Graphviz diagrams with simple, easy to maintain code.

Project description

Test Coverage Read the Docs Status View on GitHub Python Version

Generate and render Graphviz diagrams with clear, maintainable code by separating presentation from structure.

The heart of gvdot is the class Dot, a DOT language builder. Applications create diagrams using Dot methods, then either convert the instance to DOT language text or render it as SVG or an image. Users can also interactively display Dot objects in notebooks.

Example

Suppose we want to generate diagrams of nondeterministic finite automata like this:

Example NFA

represented by instances of

@dataclass
class NFA:
    alphabet : str
    delta    : dict[str, list[list[str]]]
    final    : list[str]
    start    : str

where delta["q"][0] is the list of states reached from state q by epsilon transitions, and delta["q"][i] is the list of states reached from q by symbol alphabet[i-1].

We start by defining a theme, a normal Dot object from which other dot objects can inherit graph attributes, default attributes, and roles.

nfa_theme = (Dot()
    .all_default(fontsize=12)
    .node_default(shape="circle", style="filled", fillcolor="khaki")
    .node_role("init", label="", shape="none", width=0, height=0)
    .node_role("final", shape="doublecircle", penwidth=1.25)
    .graph(rankdir="LR", labelloc="t", fontsize=16))

The theme defines two gvdot roles, collections of Graphviz attribute values that applications can assign to diagram elements by name.

Having isolated presentation attributes in a theme, our generation code is straightforward.

def nfa_diagram(nfa:NFA, title:str):

    dot = Dot(directed=True).use_theme(nfa_theme)
    dot.graph(label=Markup(f"<b>{title}</b>"))

    init_id = Nonce()
    dot.node(init_id, role="init")
    dot.edge(init_id, nfa.start)

    for state in nfa.final:
        dot.node(state, role="final")

    for state, transitions in nfa.delta.items():
        merged = defaultdict(list)
        for index, targets in enumerate(transitions):
            for target in targets:
                merged[target].append(
                    nfa.alphabet[index-1] if index > 0 else '&epsilon;')
        for target, symbols in merged.items():
            dot.edge(state, target, label=", ".join(symbols))

    return dot

We can render and save the diagram above with

example = NFA("01", {
    "s0": [["q0", "r0"], [], []],
    "q0": [[], ["q1"], ["q0"]],
    "q1": [[], ["q1"], ["q2"]],
    "q2": [[], ["q3"], ["q0"]],
    "q3": [[], ["q1"], ["q4"]],
    "q4": [[], ["q4"], ["q4"]],
    "r0": [[], ["r0"], ["r1"]],
    "r1": [[], ["r0"], ["r2"]],
    "r2": [[], ["r3"], ["r1"]],
    "r3": [[], ["r3"], ["r3"]],
}, ["q4","r0","r1","r2"], "s0")

nfa_diagram(example,"Example NFA").save("example.svg")

In a notebook, we can directly display the diagram from a cell containing

nfa_diagram(example,"Example NFA").show()

You can find this NFA example and others in the examples directory. The documentation includes a Quick Tour

Installation

Using Python 3.12 or greater, you can install gvdot with

$ pip install gvdot

To ensure the optional notebook support is enabled, use

$ pip install gvdot[ipython]

Rendering requires a Graphviz installation. You can determine if one is in your PATH with

$ dot -V

To install Graphviz, see https://graphviz.org/download.

Reliability

gvdot includes automated tests with 100% code coverage, which are run on MacOS, Linux, and Windows with Python 3.12, 3.13, and 3.14. See the GitHub workflow for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gvdot-1.2.1.tar.gz (18.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gvdot-1.2.1-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

File details

Details for the file gvdot-1.2.1.tar.gz.

File metadata

  • Download URL: gvdot-1.2.1.tar.gz
  • Upload date:
  • Size: 18.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.10

File hashes

Hashes for gvdot-1.2.1.tar.gz
Algorithm Hash digest
SHA256 2e74fd1d13ddd7dbaf6e3d2f001a177494ecfe2622ffe566d8d6bb1c42199718
MD5 75c333267295863166499df24da7be4c
BLAKE2b-256 641c52654a98441e9fa0700b231fb52c26695923ed31c736b405242543c3763f

See more details on using hashes here.

File details

Details for the file gvdot-1.2.1-py3-none-any.whl.

File metadata

  • Download URL: gvdot-1.2.1-py3-none-any.whl
  • Upload date:
  • Size: 18.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.10

File hashes

Hashes for gvdot-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a5a8d41dbb0921abf58bcd475df14ff1ceb38b01021dd13a9e76cd8d36b2b19b
MD5 9c7a2240a74ab3e2abe0deefb7cc0b72
BLAKE2b-256 b16b615b5a80b2d7774186a8dff525daf6285dbf2d203e7cc5dbae01f1cad06a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page