Search code examples
pythonsubprocessgraphviz

How to add a label to each node in Graphviz?


[EDIT] as asked here is what ps does for me :

   PID TTY          TIME CMD
  3796 pts/0    00:00:00 bash
  4811 pts/0    00:00:00 ps

I'm beginning with Graphviz and I would like to display the name of the running process. I got a script that display their number and I'm trying to add a label to each node.

The problem is that only the last write label is displayed to the root node, how can I manage to write a label to every node ?

#!/usr/bin/env python3

from subprocess import Popen, PIPE, call
import re

dot = open("psgraph.dot", "w")
dot.write("digraph G {\n")

p = Popen("ps -fe", shell=True, stdout=PIPE)
psre = re.compile(r"\w+\s+(\d+)\s+(\d+)")

p.stdout.readline() # ignore first line
for line in p.stdout:
    match = psre.search(line.decode("utf-8"))
    if match:
        if int(match.group(2)) in (0, 2):
            continue
        dot.write ("  {1} -> {0}\n".format(match.group(1), match.group(2)))

for line in p.stdout:
    match = psre.search(line.decode("utf-8"))
    if match:
        if int(match.group(2)) in (0, 2):
            continue
        dot.write ("""1 [label="loop"]\n""")

dot.write("""1 [label="laste write"]}\n""")
dot.close()

call("dot -Tpdf -O psgraph.dot", shell=True)

Solution

  • I guess something like this:

    # Update RE to capture command, too
    psre = re.compile(r"\w+\s+(\d+)\s+(\d+)\s+\d+:\d+:\d+\s(\w+)")
    
    # Collect labels
    cmds = []
    p.stdout.readline() # ignore first line
    for line in p.stdout:
        match = psre.search(line.decode("utf-8"))
        if match:
            if int(match.group(2)) in (0, 2):
                continue
            dot.write ("  {1} -> {0}\n".format(match.group(1), match.group(2)))
            cmds.append((match.group(2), match.group(3)),)
    
    for cmd, label in cmds:
        dot.write ("""{0} [label="{1}"]\n""".format(cmd, label))
    

    I'm obviously speculating about what exactly you want to write in the second loop, or indeed whether it's even necessary or useful to write all the nodes before all the labels. If you can update the question with what exactly you want here, I imagine it shouldn't be hard.