alexd
alexd

Reputation: 41

Converting a graphviz Source object to graphviz Graph object

I've got a template schematic made in raw .dot format, but I now want to populate the labels using python.

with the https://pypi.org/project/graphviz/ library I've managed to load the .dot file but don't see how I can edit it. Is it possible to convert a Source object to a Graph object, or otherwise use the methods available to the Graph object?

trying:

from graphviz import Source

src = Source('digraph "the holy hand grenade" { rankdir=LR; 1 -> 2 -> 3 -> lob }')
src.node("foo")
_ = src.render('test.gv', view=False)
Source.from_file('test.gv')

I get the error AttributeError: 'Source' object has no attribute 'node'

Upvotes: 4

Views: 2386

Answers (3)

danospanos
danospanos

Reputation: 41

Following the great answer of @Ray Ronnaret, this is what worked for me. I have no comments in my dot file, thus it becomes as simple as follows:

from graphviz import Source, Digraph

s = Source.from_file('viz.dot')
g = Digraph()

source_lines = str(s).splitlines()
# Remove 'digraph tree {'
source_lines.pop(0)
# Remove the closing brackets '}'
source_lines.pop(-1)
# Append the nodes to body
g.body += source_lines

Then, I was able to edit the graph.

g.graph_attr['rankdir'] = 'LR'
g.unflatten(stagger=3).render()

Upvotes: 3

Ray Ronnaret
Ray Ronnaret

Reputation: 166

I do parse the grapviz.source eliminate non necessary char and append back. This work for me. Note that this assume first line may be contain comment. Thing remains is to make it be function.

src = Source.from_file('Source.gv')
lst = str(src).splitlines()
HasComment =  (lst[0].find('//') != -1)

IsDirectGraph = False
skipIndex  = 0

if HasComment:
    skipIndex = 1
    if lst[skipIndex].find('graph {')!=-1 :
        IsDirectGraph= False
else:
    if lst[0].find('graph {')!=-1 :
        IsDirectGraph= False 

if IsDirectGraph:
    g = Digraph()
else:
    g = Graph()
    
g.body.clear()
        
s = str()
for i in range(len(lst)):
    if( (i>skipIndex) and (i!=len(lst)-1) ):
        if HasComment:
            g.comment = lst[0].replace('//','')
        g.body.append(lst[i])
print(g.source)       
display(g)
       

Upvotes: 1

alexd
alexd

Reputation: 41

https://github.com/xflr6/graphviz/issues/76

answers the question that it is not possible with that library, but other ones are available which can.

Upvotes: 0

Related Questions