Reputation: 788
I am having trouble visualizing a multidirectional graph with parallel edges in networkx so I have resorted to using pydot, but I am having two issues
1) I cant seem to understand why the node positions are not being fixed I would like to plot them at the x and y specified coordinates 2) How do I set the size of the figure being plotted the plt.figure command does not really work 3) How do I add edge labels (if I had them)
many thanks
import networkx as nx
from io import StringIO
from io import BytesIO
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import networkx as nx
graph= nx.MultiGraph()
#add 4 nodes in the vertexs of a square. X and Y are the coordinates
graph.add_node(1,x=100,y=100)
graph.add_node(2,x=100,y=200)
graph.add_node(3,x=200,y=100)
graph.add_node(4,x=200,y=200)
graph.add_edge(1,2)
graph.add_edge(2,1)
graph.add_edge(3,1)
graph.add_edge(3,4)
graph.add_edge(4,1)
# assign positions
for n in graph:
graph.node[n]['pos'] = '"%d,%d"'%(graph.node[n]['x'], graph.node[n]['y'])
p = nx.drawing.nx_pydot.to_pydot(graph)
# render pydot by calling dot, no file saved to disk
png_str = p.create_png(prog='C:\\Anaconda3\\Library\\bin\\graphviz\\dot.exe')
# treat the dot output string as an image file
sio = BytesIO()
sio.write(png_str)
sio.seek(0)
img = mpimg.imread(sio)
plt.figure(figsize = (10,10))
imgplot = plt.imshow(img)
Upvotes: 2
Views: 2810
Reputation: 6801
digraph G {
graph [bb="0,0,270,396",
sep="+6",
splines=true
];
node [label="\N",
nodesep=.4,
pin=true,
style=invis
];
edge [style=invis];
{
graph [rank=same];
node [style=solid];
1 [height=0.5,
pos="27,378",
width=0.75];
}
{
graph [rank=same];
node [style=solid];
2 [height=0.5,
pos="27,306",
width=0.75];
3 [height=0.5,
pos="99,306",
width=0.75];
5 [height=0.5,
pos="243,306",
width=0.75];
}
{
graph [rank=same];
node [style=solid];
c1 [height=0.5,
pos="27,234",
style=invis,
width=0.75];
6 [height=0.5,
pos="99,234",
width=0.75];
}
1 -> 2 [pos="e,27,324.1 27,359.7 27,351.98 27,342.71 27,334.11"];
2 -> c1 [pos="e,27,252.1 27,287.7 27,279.98 27,270.71 27,262.11"];
edge[constraint=false style=solid]
1 -> 2 [label=aaa ]
1 -> 3 [label=abb]
1 -> 5 [label=abc ]
1 -> 6 [label=aba]
3 -> 6
}
Linux command to run neato - note the "-s" option
F=stylized1Tiny; neato -s -Tpng $F.dot >$F.png;
Upvotes: 0
Reputation: 20175
TLDR (a) use neato, not dot to draw (b) pos attrs should be of the form "100,200!" in the dot file. Don't double-quote it, and add an ! mark.
Firstly, not all of the graphviz tools support positions. See docs:
In neato and fdp, pos can be used to set the initial position of a node
Secondly, once you are using a tool that reads the pos
attribute, you'll see some errors in the output. To understand problems with an external tool, it makes more sense to test it in isolation, so let's do that to file:
nx.drawing.write_dot(graph, "test.dot")
And then run neato
:
> neato -Tpng test.dot >test1.png
Error: node 1, position "100,100", expected two doubles
Error: node 2, position "100,200", expected two doubles
Error: node 3, position "200,100", expected two doubles
Error: node 4, position "200,200", expected two doubles
You'll now see that the format isn't right. And so neato proceeds to layout the graph as if pos
wasn't specified.
for n in graph:
graph.node[n]['pos'] = "{},{}!".format(
graph.node[n]['x'], graph.node[n]['y'])
Now try again:
nx.drawing.write_dot(graph, "test_fix.dot")
# note: the -n flag causes neato to use points rather than inches.
# see docs, and/or experiment with -s setting as well
> neato -n -Tpng test_fix.dot >test2.png
And positions are now respected:
The dot manual and this site both have info on how to draw edge labels (e.g. How to add edge labels in Graphviz? or Graphviz: Place edge label on the other side (II)), and obviously you need to add some property to your graph (see "associate data to edges using keywords": https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.DiGraph.add_edge.html )
It isn't clear what you mean by "plt.figure command does not really work" but this is quite far from the networkx issues here so I think it would be better to post a new question that isolates the problem and explains it fully.
Upvotes: 4