使用 Networkx 的 Königsberg 桥梁
Königsberg Bridges using Networkx
我正在尝试使用 NetworkX 和 Python 3.8
绘制著名的 Königsberg Bridges 问题的图表
这是我正在使用的代码:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G=nx.Graph()
G.add_node(1) ## Land A
G.add_node(2) ## Land B
G.add_node(3) ## Land C
G.add_node(4) ## Land D
## Connected Edges
G.add_edge(1,3,color='r',weight=1) ## Bridge 1
G.add_edge(1,3,color='r',weight=1) ## Bridge 2
G.add_edge(1,4,color='r',weight=1) ## Bridge 3
G.add_edge(3,4,color='r',weight=1) ## Bridge 4
G.add_edge(1,2,color='r',weight=1) ## Bridge 5
G.add_edge(1,2,color='r',weight=1) ## Bridge 6
G.add_edge(2,4,color='r',weight=1) ## Bridge 7
colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()
names = {1:"Land A",2:"Land B",3:"Land C",4:"Land D"}
H=nx.relabel_nodes(G,names)
pos = nx.circular_layout(H)
nx.draw_networkx(H,pos,edge_color=colors,width=list(weights))
plt.savefig("konigsberg_bridges_graph.png")
plt.show()
生成的图是这个:
问题是与互联网上出现的图表有很大不同:
我怎样才能使用 NetworkX 制作类似于那个图表的图表?
要扩展注释,您需要 MultiGraph
用于两个节点之间的多个边:
G=nx.MultiGraph()
G.add_node(1) ## Land A
G.add_node(2) ## Land B
G.add_node(3) ## Land C
G.add_node(4) ## Land D
## Connected Edges
G.add_edge(1,3,color='r',weight=1) ## Bridge 1
G.add_edge(1,3,color='r',weight=1) ## Bridge 2
G.add_edge(1,4,color='r',weight=1) ## Bridge 3
G.add_edge(3,4,color='r',weight=1) ## Bridge 4
G.add_edge(1,2,color='r',weight=1) ## Bridge 5
G.add_edge(1,2,color='r',weight=1) ## Bridge 6
G.add_edge(2,4,color='r',weight=1) ## Bridge 7
colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()
names = {1:"Land A",2:"Land B",3:"Land C",4:"Land D"}
H=nx.relabel_nodes(G,names)
要可视化网络,您可以使用显示平行边的 Graphviz。您可以在 dot
中编写图表并使用 graphviz.Source
:
显示图表
path = 'multig.dot'
nx_pydot.write_dot(H, path)
Source.from_file(path)
我不确定这是否算作答案,但我发现使用 LaTeX 和 TikZ 绘制柯尼斯堡桥图更容易
这是代码:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[thick, main/.style = {draw, circle}]
\node[main,scale=0.6, label=left:$a$] (a) at (0,0) {};
\node[main,scale=0.6, label=left:$b$] (b) at (0,2) {};
\node[main,scale=0.6, label=left:$c$] (c) at (0,4) {};
\node[main,scale=0.6, label=right:$d$] (d) at (4,2) {};
\draw (a) -- (d);
\draw (b) -- (d);
\draw (c) -- (d);
\draw (a) to [out=120,in=240,looseness=1] (b);
\draw (a) to [out=60,in=300,looseness=1] (b);
\draw (b) to [out=120,in=240,looseness=1] (c);
\draw (b) to [out=60,in=300,looseness=1] (c);
\end{tikzpicture}
\end{document}
结果图像是:
也可以使用python创建一个tex文件,这样也可以使用NetworkX,这是代码:
import os
import networkx as nx
G=nx.Graph()
G.add_node('1', land="a") ## Land A
G.add_node('2', land="b") ## Land B
G.add_node('3', land="c") ## Land C
G.add_node('4', land="d") ## Land D
## Connected Edges
G.add_edge(1, 3) ## Bridge 1
G.add_edge(1, 3) ## Bridge 2
G.add_edge(1, 4) ## Bridge 3
G.add_edge(3, 4) ## Bridge 4
G.add_edge(1, 2) ## Bridge 5
G.add_edge(1, 2) ## Bridge 6
G.add_edge(2, 4) ## Bridge 7
with open('konigsberg.tex','w') as file:
file.write('\documentclass[margin=1mm]{standalone}\n')
file.write('\usepackage{tikz} \n')
file.write('\begin{document}\n')
file.write('\begin{tikzpicture}[thick, main/.style = {draw, circle}] \n')
file.write('\node[main,scale=0.6, label=left:$' + G.nodes['1']['land'] + '$] (' + G.nodes['1']['land'] + ') at (0,0) {}; \n')
file.write('\node[main,scale=0.6, label=left:$' + G.nodes['2']['land'] + '$] (' + G.nodes['2']['land'] + ') at (0,2) {}; \n')
file.write('\node[main,scale=0.6, label=left:$' + G.nodes['3']['land'] + '$] (' + G.nodes['3']['land'] + ') at (0,4) {}; \n')
file.write('\node[main,scale=0.6, label=right:$' + G.nodes['4']['land'] + '$] (' + G.nodes['4']['land'] + ') at (4,2) {}; \n')
file.write('\draw (' + G.nodes['1']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
file.write('\draw (' + G.nodes['2']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
file.write('\draw (' + G.nodes['3']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
file.write('\draw (' + G.nodes['1']['land'] + ') to [out=120,in=240,looseness=1] (' + G.nodes['2']['land'] + '); \n')
file.write('\draw (' + G.nodes['1']['land'] + ') to [out=60,in=300,looseness=1] (' + G.nodes['2']['land'] + '); \n')
file.write('\draw (' + G.nodes['2']['land'] + ') to [out=120,in=240,looseness=1] (' + G.nodes['3']['land'] + '); \n')
file.write('\draw (' + G.nodes['2']['land'] + ') to [out=60,in=300,looseness=1] (' + G.nodes['3']['land'] + '); \n')
file.write('\end{tikzpicture} \n')
file.write('\end{document}\n')
os.system("pdflatex konigsberg.tex")
运行 此代码使用 Python3 和 Ubuntu 20.04 生成相同的图
我正在尝试使用 NetworkX 和 Python 3.8
绘制著名的 Königsberg Bridges 问题的图表这是我正在使用的代码:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G=nx.Graph()
G.add_node(1) ## Land A
G.add_node(2) ## Land B
G.add_node(3) ## Land C
G.add_node(4) ## Land D
## Connected Edges
G.add_edge(1,3,color='r',weight=1) ## Bridge 1
G.add_edge(1,3,color='r',weight=1) ## Bridge 2
G.add_edge(1,4,color='r',weight=1) ## Bridge 3
G.add_edge(3,4,color='r',weight=1) ## Bridge 4
G.add_edge(1,2,color='r',weight=1) ## Bridge 5
G.add_edge(1,2,color='r',weight=1) ## Bridge 6
G.add_edge(2,4,color='r',weight=1) ## Bridge 7
colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()
names = {1:"Land A",2:"Land B",3:"Land C",4:"Land D"}
H=nx.relabel_nodes(G,names)
pos = nx.circular_layout(H)
nx.draw_networkx(H,pos,edge_color=colors,width=list(weights))
plt.savefig("konigsberg_bridges_graph.png")
plt.show()
生成的图是这个:
问题是与互联网上出现的图表有很大不同:
我怎样才能使用 NetworkX 制作类似于那个图表的图表?
要扩展注释,您需要 MultiGraph
用于两个节点之间的多个边:
G=nx.MultiGraph()
G.add_node(1) ## Land A
G.add_node(2) ## Land B
G.add_node(3) ## Land C
G.add_node(4) ## Land D
## Connected Edges
G.add_edge(1,3,color='r',weight=1) ## Bridge 1
G.add_edge(1,3,color='r',weight=1) ## Bridge 2
G.add_edge(1,4,color='r',weight=1) ## Bridge 3
G.add_edge(3,4,color='r',weight=1) ## Bridge 4
G.add_edge(1,2,color='r',weight=1) ## Bridge 5
G.add_edge(1,2,color='r',weight=1) ## Bridge 6
G.add_edge(2,4,color='r',weight=1) ## Bridge 7
colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()
names = {1:"Land A",2:"Land B",3:"Land C",4:"Land D"}
H=nx.relabel_nodes(G,names)
要可视化网络,您可以使用显示平行边的 Graphviz。您可以在 dot
中编写图表并使用 graphviz.Source
:
path = 'multig.dot'
nx_pydot.write_dot(H, path)
Source.from_file(path)
我不确定这是否算作答案,但我发现使用 LaTeX 和 TikZ 绘制柯尼斯堡桥图更容易
这是代码:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[thick, main/.style = {draw, circle}]
\node[main,scale=0.6, label=left:$a$] (a) at (0,0) {};
\node[main,scale=0.6, label=left:$b$] (b) at (0,2) {};
\node[main,scale=0.6, label=left:$c$] (c) at (0,4) {};
\node[main,scale=0.6, label=right:$d$] (d) at (4,2) {};
\draw (a) -- (d);
\draw (b) -- (d);
\draw (c) -- (d);
\draw (a) to [out=120,in=240,looseness=1] (b);
\draw (a) to [out=60,in=300,looseness=1] (b);
\draw (b) to [out=120,in=240,looseness=1] (c);
\draw (b) to [out=60,in=300,looseness=1] (c);
\end{tikzpicture}
\end{document}
结果图像是:
也可以使用python创建一个tex文件,这样也可以使用NetworkX,这是代码:
import os
import networkx as nx
G=nx.Graph()
G.add_node('1', land="a") ## Land A
G.add_node('2', land="b") ## Land B
G.add_node('3', land="c") ## Land C
G.add_node('4', land="d") ## Land D
## Connected Edges
G.add_edge(1, 3) ## Bridge 1
G.add_edge(1, 3) ## Bridge 2
G.add_edge(1, 4) ## Bridge 3
G.add_edge(3, 4) ## Bridge 4
G.add_edge(1, 2) ## Bridge 5
G.add_edge(1, 2) ## Bridge 6
G.add_edge(2, 4) ## Bridge 7
with open('konigsberg.tex','w') as file:
file.write('\documentclass[margin=1mm]{standalone}\n')
file.write('\usepackage{tikz} \n')
file.write('\begin{document}\n')
file.write('\begin{tikzpicture}[thick, main/.style = {draw, circle}] \n')
file.write('\node[main,scale=0.6, label=left:$' + G.nodes['1']['land'] + '$] (' + G.nodes['1']['land'] + ') at (0,0) {}; \n')
file.write('\node[main,scale=0.6, label=left:$' + G.nodes['2']['land'] + '$] (' + G.nodes['2']['land'] + ') at (0,2) {}; \n')
file.write('\node[main,scale=0.6, label=left:$' + G.nodes['3']['land'] + '$] (' + G.nodes['3']['land'] + ') at (0,4) {}; \n')
file.write('\node[main,scale=0.6, label=right:$' + G.nodes['4']['land'] + '$] (' + G.nodes['4']['land'] + ') at (4,2) {}; \n')
file.write('\draw (' + G.nodes['1']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
file.write('\draw (' + G.nodes['2']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
file.write('\draw (' + G.nodes['3']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
file.write('\draw (' + G.nodes['1']['land'] + ') to [out=120,in=240,looseness=1] (' + G.nodes['2']['land'] + '); \n')
file.write('\draw (' + G.nodes['1']['land'] + ') to [out=60,in=300,looseness=1] (' + G.nodes['2']['land'] + '); \n')
file.write('\draw (' + G.nodes['2']['land'] + ') to [out=120,in=240,looseness=1] (' + G.nodes['3']['land'] + '); \n')
file.write('\draw (' + G.nodes['2']['land'] + ') to [out=60,in=300,looseness=1] (' + G.nodes['3']['land'] + '); \n')
file.write('\end{tikzpicture} \n')
file.write('\end{document}\n')
os.system("pdflatex konigsberg.tex")
运行 此代码使用 Python3 和 Ubuntu 20.04 生成相同的图