Skip to main content

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, 3.14, and 3.15. See the GitHub workflow for details.

Metadata

Release files for gvdot 1.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gvdot 1.3.0
File Size Uploaded Provenance Actions
gvdot-1.3.0.tar.gz 29.1 kB Without provenance Details for gvdot-1.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for gvdot 1.3.0
File Interpreter ABI Platform Actions
gvdot-1.3.0-py3-none-any.whl Python 3 none any Details for gvdot-1.3.0-py3-none-any.whl

Total release size: 56.1 kB

Release files / gvdot-1.3.0.tar.gz

Download URL gvdot-1.3.0.tar.gz
Size 29.1 kB
Tags Source
SHA-256 checksum
How to use checksums
a0eeba032db78d2a4b727e640bb9a2c87f167c6682d4cb0f098b2d0ab8c46419
BLAKE2b-256 checksum
How to use checksums
e5a82a069829b6b69c73a84e9060fb42bd72dc4c4a0c0cfc0909290f64d5c49e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.1

Release files / gvdot-1.3.0-py3-none-any.whl

Download URL gvdot-1.3.0-py3-none-any.whl
Size 27.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
713083af93143740ea190ff13eb2cedd03c6e37bbea20f6889656979b6771652
BLAKE2b-256 checksum
How to use checksums
d0c4d6bb55a8c0ad3237eaa19f928a1335d4ec3f3eeff1e7634a2ad82b2f2c6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.1

Security for gvdot 1.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page