Skip to main content

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

Project description

PyPI Version Read the Docs Status View on GitHub

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 graph expression. Applications create diagrams using dot object methods, then either convert the object 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}<br/></b>"))

    dot.node("_init_", role="init")
    dot.edge("_init_", 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.

Documentation

See gvdot.readthedocs.io for an overview and reference.

Installation

You can install gvdot from PyPI with

$ pip install gvdot

To ensure the optional notebook support is enabled, use

$ pip install gvdot[ipython]

You can also clone the repository and install it directly.

$ git clone https://github.com/escreven/gvdot.git
$ cd gvdot
$ pip install .

gvdot requires Python 3.12 or greater.

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-0.9.2.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

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

gvdot-0.9.2-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for gvdot-0.9.2.tar.gz
Algorithm Hash digest
SHA256 d28f536c9184bedc56dbe4981a3e055c8295a0b89913ca9ce0bf648bd4be2691
MD5 63a7ee082b4e4de70b2874ab4c6cf92d
BLAKE2b-256 8e9bc4109f6dc164753d8c463810c2455c4c575dc467b27e362a6d5932df4e3e

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for gvdot-0.9.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5423d739cabe23e84b52ebce38812814058166bf787c54e73edf7de626b0440c
MD5 e3ce660d899f5fb8cbdf3bdd1b52359f
BLAKE2b-256 5d1b5f2f7b5b89299956c13d63d0c6c56440c737ba9ad69df4dae3e05f60aedf

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