Pokazano je na nekoliko primjera korištenje GraphViz-a unutar SAGE-a. Detaljniji help o GraphViz-u možete pronaći na webu. GraphViz je napredni alat za automatsko crtanje grafova. Ovdje će biti pokazane samo neke od opcija. GraphViz ima puno opcija kojima se određuje izgled grafa i nemoguće je baš sve ih ovdje navesti.
import sage.misc.banner
banner()
from IPython.core.display import Image
graf1=Graph({0:[1,2,3],1:[1,1,1],2:[2,4,4],3:[4,4,4]})
SAGE
graf1.plot(graph_border=True)
GraphViz
s1=graf1.graphviz_string()
print(s1)
različiti rasporedi vrhova pomoću opcija: neato, fdp, sfdp, twopi, circo.
os.system("echo '%s' | dot -Tpng > graf1.png" % s1)
Image(filename="graf1.png")
os.system("echo '%s' | dot -Kcirco -Tpng > graf2.png" % s1)
Image(filename="graf2.png")
os.system("echo '%s' | dot -Kneato -Tpng > graf3.png" % s1)
Image(filename="graf3.png")
os.system("echo '%s' | dot -Kfdp -Tpng > graf4.png" % s1)
Image(filename="graf4.png")
os.system("echo '%s' | dot -Ktwopi -Tpng > graf5.png" % s1)
Image(filename="graf5.png")
želimo li drukčiji izlaz od PNG-a
os.system("echo '%s' | dot -Teps > graf1.eps" % s1)
os.system("echo '%s' | dot -Tpdf > graf1.pdf" % s1)
možemo sami konstruirati direktno GraphViz graf dodajući još mnoge druge opcije (naravno, treba proučiti dot jezik; na webu postoje helpovi o tome).
neke opcije za prikaz vrhova grafa
možemo definirati globalno opcije koje će vrijediti za sve vrhove
s2="""graph {\n node[width=0.1,height=0.1,shape=circle, fontsize=10, fontcolor=red,fillcolor=yellow,style=filled,margin=0]\n
"0" [label="root"];\n "1" [label="1"];\n "2" [label="2"];\n "3" [label="3"];\n "4" [label="4"];\n
"0" -- "1";\n "0" -- "2";\n "0" -- "3";\n "1" -- "1";\n "1" -- "1";\n "1" -- "1";\n "2" -- "2";\n "2" -- "4";\n
"2" -- "4";\n "3" -- "4";\n "3" -- "4";\n "3" -- "4";\n}"""
print(s2)
os.system("echo '%s' | dot -Tpng > graf6.png" % s2)
Image(filename="graf6.png")
os.system("echo '%s' | dot -Kfdp -Tpng > graf7.png" % s2)
Image(filename="graf7.png")
možemo i lokalno urediti svaki pojedini vrh ukoliko želimo da izgleda drukčije od ostalih vrhova
s3="""graph {\n node [width=0.3,height=0.3 fontsize=10, fontcolor=red,fillcolor=yellow,style=filled,margin=0]\n
"0" [label="root"];\n "1" [label="1",shape=hexagon,fontsize=18,margin=0.2];\n
"2" [label="2", fillcolor=mintcream, fontcolor=purple];\n "3" [label="3",shape=house];\n
"4" [label="4", shape=doublecircle];\n\n "0" -- "1";\n "0" -- "2";\n "0" -- "3";\n
"1" -- "1";\n "1" -- "1";\n "1" -- "1";\n "2" -- "2";\n "2" -- "4";\n "2" -- "4";\n
"3" -- "4";\n "3" -- "4";\n "3" -- "4";\n}"""
print(s3)
os.system("echo '%s' | dot -Tpng > graf8.png" % s3)
Image(filename="graf8.png")
os.system("echo '%s' | dot -Kcirco -Tpng > graf9.png" % s3)
Image(filename="graf9.png")
neke opcije za prikaz bridova
s4="""graph {\n node [width=0.3,height=0.3 fontsize=10, fontcolor=red,fillcolor=yellow,style=filled, margin=0]\n
edge [color=blue,style=bold,tailport=s,headport=n]\n "0" [label="root"];\n
"1" [label="1",shape=hexagon,margin=0.2,fontsize=18];\n
"2" [label="2", fillcolor=mintcream, fontcolor=purple];\n "3" [label="3",shape=house];\n
"4" [label="4", shape=doublecircle];\n\n "0" -- "1";\n "0" -- "2";\n
"0" -- "3";\n "1" -- "1";\n "1" -- "1";\n "1" -- "1";\n "2" -- "2";\n "2" -- "4";\n "2" -- "4";\n
"3" -- "4";\n "3" -- "4";\n "3" -- "4";\n}"""
print(s4)
os.system("echo '%s' | dot -Tpng > graf10.png" % s4)
Image(filename="graf10.png")
s5="""graph {\n node [width=0.3,height=0.3 fontsize=10, fontcolor=red,fillcolor=yellow,style=filled, margin=0]\n
edge [color=blue,fontsize=10]\n "0" [label="root"];\n
"1" [label="1",shape=hexagon,margin=0.2,fontsize=18];\n "2" [label="2", fillcolor=mintcream, fontcolor=purple];\n
"3" [label="3",shape=house];\n "4" [label="4", shape=doublecircle];\n\n
"0" -- "1" [taillabel="tri",labelangle=10,labelfontcolor=red,labeldistance=4];\n
"0" -- "2" [label="dva",decorate=true];\n "0" -- "3";\n "1" -- "1";\n
"1" -- "1" [style=dotted];\n "1" -- "1";\n "2" -- "2";\n "2" -- "4";\n
"2" -- "4";\n "3" -- "4";\n "3" -- "4";\n "3" -- "4";\n}"""
print(s5)
os.system("echo '%s' | dot -Tpng > graf11.png" % s5)
Image(filename="graf11.png")
Usmjereni graf
digraf1=DiGraph({0:[1,2,3],1:[1,1,1],2:[2,4,4],3:[4,4,4]})
digraf1.plot(graph_border=True,vertex_size=300)
s6=digraf1.graphviz_string()
print(s6)
os.system("echo '%s' | dot -Tpng > digraf1.png" % s6)
Image(filename="digraf1.png")
s7="""digraph {\n edge [color=blue,fontsize=10,arrowhead=vee]\n
"0" [label="0"];\n "1" [label="1"];\n "2" [label="2"];\n "3" [label="3"];\n
"4" [label="4"];\n "0" -> "1";\n "0" -> "2";\n
"0" -> "3" [dir=both,arrowhead=odiamond,arrowtail=dot,color=red];\n
"1" -> "1";\n "1" -> "1";\n "1" -> "1";\n "2" -> "2";\n
"2" -> "4" [headlabel="2->4",labelangle=20,labeldistance=4];\n
"2" -> "4";\n "3" -> "4";\n "3" -> "4";\n "3" -> "4";\n}"""
print(s7)
os.system("echo '%s' | dot -Tpng > digraf2.png" % s7)
Image(filename="digraf2.png")
s8="""digraph {\n node [style=filled,fillcolor=yellow] edge [color=blue,fontsize=10,arrowhead=vee]\n
"0" [label="0"];\n "1" [label="1"];\n "2" [label="2"];\n "3" [label="3"];\n "4" [label="4"];\n
"0" -> "1"[weight=2];\n "0" -> "2";\n "0" -> "3" [dir=both,arrowhead=odiamond,arrowtail=dot,color=red];\n
"1" -> "1";\n "1" -> "1";\n "1" -> "1";\n "2" -> "2";\n
"2" -> "4" [headlabel="2->4",labelangle=35,labeldistance=5];\n
"2" -> "4";\n "3" -> "4";\n "3" -> "4";\n "3" -> "4";\n}"""
print(s8)
os.system("echo '%s' | dot -Kcirco -Tpng > digraf3.png" % s8)
Image(filename="digraf3.png")
Petersenov graf
P=graphs.PetersenGraph()
P.plot(graph_border=True,figsize=[4,4])
Pstr=P.graphviz_string()
print(Pstr)
os.system("echo '%s' | dot -Tpng > petersen.png" % Pstr)
Image(filename="petersen.png")
Pstr2="""graph {\n "0" [label="0"];\n "1" [label="1",shape=box,style=filled];\n "2" [label="2"];\n "3" [label="3"];\n
"4" [label="4"];\n "5" [label="5"];\n "6" [label="6"];\n "7" [label="7"];\n "8" [label="8"];\n "9" [label="9"];\n\n
"0" -- "1";\n "0" -- "4";\n "0" -- "5";\n "1" -- "2";\n "1" -- "6";\n "2" -- "3";\n "2" -- "7";\n "3" -- "4";\n
"3" -- "8";\n "4" -- "9";\n "5" -- "7";\n "5" -- "8";\n "6" -- "8";\n "6" -- "9";\n
"7" -- "9";\n {rank=same; "0" "1" "2" "3" "4"}\n {rank=same; "5" "6" "7" "8" "9"}}"""
print(Pstr2)
os.system("echo '%s' | dot -Tpng > petersen2.png" % Pstr2)
Image(filename="petersen2.png")
os.system("echo '%s' | dot -Kcirco -Tpng > petersen3.png" % Pstr2)
Image(filename="petersen3.png")
Pstr3="""graph {\n splines=true\n node [width=0.3,height=0.2,margin=0]\n
"0" [label="0"];\n "1" [label="1",shape=box,style=filled];\n "2" [label="2"];\n
"3" [label="3"];\n "4" [label="4"];\n "5" [label="5"];\n "6" [label="6"];\n
"7" [label="7"];\n "8" [label="8"];\n "9" [label="9"];\n\n "0" -- "1";\n
"0" -- "4";\n "0" -- "5";\n "1" -- "2";\n "1" -- "6";\n "2" -- "3";\n
"2" -- "7";\n "3" -- "4";\n "3" -- "8";\n "4" -- "9";\n "5" -- "7";\n
"5" -- "8";\n "6" -- "8";\n "6" -- "9";\n "7" -- "9";}"""
print(Pstr3)
os.system("echo '%s' | dot -Ktwopi -Tpng > petersen4.png" % Pstr2)
Image(filename="petersen4.png")
os.system("echo '%s' | dot -Ktwopi -Tpng > petersen5.png" % Pstr3)
Image(filename="petersen5.png")
Graf s puno vrhova i bridova
random graf sa 200 vrhova i 500 bridova
graf2=graphs.RandomGNM(200,500)
graf2.plot(graph_border=True)
graf2.plot(graph_border=True,vertex_labels=False,vertex_size=10)
Graphviz-u je ipak jako stalo da se svi vrhovi i bridovi čim jasnije vide pa je zato i konačna slika većih dimenzija
os.system("echo '%s' | dot -Tpng > graf_random.png" % graf2.graphviz_string())
Image(filename="graf_random.png")
radijalni raspored vrhova ipak nije u ovom slučaju najbolje rješenje
os.system("echo '%s' | dot -Ktwopi -Tpng > graf_random2.png" % graf2.graphviz_string())
Image(filename="graf_random2.png")
os.system("echo '%s' | dot -Kfdp -Tpng > graf_random3.png" % graf2.graphviz_string())
Image(filename="graf_random3.png")
možemo pomoću opcije splines=true dobiti ljepšu sliku. Crtanje slike može malo dulje trajati u ovom slučaju pa budite strpljivi.
string3=graf2.graphviz_string()[0:10]+'splines=true\n '+graf2.graphviz_string()[10:]
os.system("echo '%s' | dot -Kfdp -Tpng > graf_random4.png" % string3)
Image(filename="graf_random4.png")
Navest ćemo nekoliko primjera korištenja NetworkX modula za crtanje grafova unutar SAGE-a. Taj pythonov modul smo već ranije koristili i koristit ćemo ga i kasnije na puno mjesta za razne druge probleme iz teorije grafova.
import networkx as nx
from pylab import *
papus=nx.pappus_graph()
papus.edges()
nx.draw(papus,with_labels=True,node_color='y')
postoji također puno dodatnih opcija za šminkanje grafa. Napišite help(nx.draw), help(nx.draw_networkx) za popis dodatnih opcija ili pogledajte na web stranicama help o matplotlib i networkx modulima.
figure(figsize=(5,5))
nx.draw_circular(papus,node_color="yellow",node_shape='v',node_size=700,edge_cmap=cm.Spectral,
edge_color=range(papus.number_of_edges()),edgecolors='k',with_labels=True)
figure(figsize=(5,5))
nx.draw_spring(papus,with_labels=True,node_color='y')
primjeri grafova s puno vrhova i bridova
geom=nx.random_geometric_graph(200,0.14)
geom.number_of_nodes(),geom.number_of_edges()
figure(figsize=(8,8))
nx.draw_random(geom,node_size=10)
Pregledniju sliku dobijemo pomoću Graphviz-a.
geomSage=Graph(Matrix(nx.to_numpy_matrix(geom,dtype=int)))
os.system("echo '%s' | dot -Tpng > geom.png" % geomSage.graphviz_string())
Image(filename="geom.png")