Skip to main content

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

Project description

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

The heart of gvdot is class Dot, a DOT language graph expression. Applications create diagrams using dot object methods, then either convert the object to a DOT language string 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 non-deterministic finite automata like this

Example NFA

represented as instances of

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

where delta["q"][i] is the list of states reached from $q$ by the $i^\text{th}$ input alphabet symbol.

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))

A gvdot role is a collection Graphviz attribute values applications can assign to diagram elements by name.

Having isolated presentation attributes in a theme, our generation code is clean and easy to maintain.

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")

with open("example.svg","w") as f:
    print(nfa_diagram(example,"Example NFA").to_svg(), file=f)

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

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

You can find this NFA example and others in the examples directory.

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.1.tar.gz (14.3 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.1-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: gvdot-0.9.1.tar.gz
  • Upload date:
  • Size: 14.3 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.1.tar.gz
Algorithm Hash digest
SHA256 119e20df97191d6a22d10c78d1c5915cfc3161f49527f03478ab86daf8ca5ea0
MD5 f2a82d736edc1d8d001d45d876887daf
BLAKE2b-256 64145989df59d728af7936d1c4f449f61b588b48a04cee469dac1445bfd4be98

See more details on using hashes here.

File details

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

File metadata

  • Download URL: gvdot-0.9.1-py3-none-any.whl
  • Upload date:
  • Size: 14.4 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 71ce46cc44160d99115a8b94535d2fb8479e5e6c30c40781b8b1ebb2e34cf5ed
MD5 abe4586ca93e91fbbda6dada565efdbd
BLAKE2b-256 d59bc5bb6374d068705bf0f930ba25feb9418009a8bb672a4666af04d5abdcf3

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