2 回答

TA貢獻1809條經驗 獲得超8個贊
根據您問題中提供的信息,我做出了以下假設:
您要確保邊緣長度基于邊緣權重
你想突出主節點
現在讓我們從第一個開始。
1. 根據邊權繪制邊長?您可以使用pygraphviz 和networkx 以邊長根據您的選擇來獲得圖形的布局。
為此,首先您需要縮放邊權重,以便節點之間的距離在圖中可見(假定您的最小值為0.1
和最大值為1
,則邊將不可見)。我將它們縮放了 10,但您可以使用適合您的任何縮放方法。
new_edge_weights?=?[?int(x*10)?for?x?in?edge_weights]
接下來,創建字典,鍵為“len”(pygraphviz 將使用此屬性),值為邊長
lengths = {}
for e,l in zip(edges, new_edge_weights):
? ? lengths[e] = dict(len=l)
# {(1, 0): {'len': 10},
# (2, 0): {'len': 5},
# (3, 1): {'len': 5},
# (4, 1): {'len': 1},
# (5, 1): {'len': 1},
# (6, 2): {'len': 1},
# (7, 2): {'len': 1}}
現在使用 graphviz_layout 獲取節點的位置并繪制圖形
pos = graphviz_layout(G, prog='neato')
nx.draw_networkx(G, pos=pos,
? ? ? ? node_size = node_sizes,
? ? ? ? node_color = node_color,
? ? ? ? edge_weights='len',
? ? ? ? labels = node_label,
? ? ? ? with_labels=True)
這是您的圖形最終的樣子:
2. 突出顯示您的主節點(假設主節點是node 0: Printer。這可能有點棘手。因此,一種方法是在主節點本身上繪制另一個尺寸更小、顏色不同的節點。
# Set the nodel label to empty for the new node
node_label[len(node_label)+1] = ""?
# Set the size of the new node smaller than the master node
master_idx = 0
node_sizes.append(node_sizes[master_idx]-300)
# change the master node color to black
node_color[master_idx] = "#000000"
# set the color of the inner node (new smaller node)
node_color.append("#00d992")
# Set the position of the node same as the master node
pos[len(pos)+1] = pos[master_idx]
# Add node to the graph
G.add_node(len(node_label))
# Draw the graph
nx.draw_networkx(G,
? ? pos=pos,
? ? node_size = node_sizes,
? ? node_color = node_color,
? ? edge_weights='len',
? ? labels = node_label,
? ? with_labels=True)
請注意,我已縮放節點大小以使邊緣可見。您可以根據您的要求更改它并相應地調整邊緣長度。
Here is the full program
import wx
import matplotlib.pyplot as plt
import networkx as nx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
from networkx.drawing.nx_agraph import graphviz_layout
class NetworkFrame(wx.Frame):
? ? def __init__(self):
? ? ? ? wx.Frame.__init__(self, None, -1)
? ? ? ? self.SetSize(wx.Size(1280, 768))
? ? ? ? ? ? ? ?
? ? ? ? self.panel = wx.Panel(self)
? ? ? ? self.fig = plt.figure()
? ? ? ? self.canvas = FigCanvas(self.panel, -1, self.fig)
? ? ? ? ? ? ? ??
? ? ? ? G = nx.Graph()
? ? ? ??
? ? ? ? nodes = [0,1,2,3,4,5,6,7]
? ? ? ? node_sizes = [650,400,400,250,250,250,250,250]
? ? ? ? node_sizes = [x+1500 for x in node_sizes]
? ? ? ? node_color = ["#00d992","#00d9c8","#00d9c8","#00b4d9","#00b4d9","#00b4d9","#00b4d9","#00b4d9"]
? ? ? ? edges = [(1,0),(2,0),(3,1),(4,1),(5,1),(6,2),(7,2)]
? ? ? ? node_label = {0: "Printer",
? ? ? ? ? ? ? ? ? ? 1: "Case",
? ? ? ? ? ? ? ? ? ? 2: "Electronics",
? ? ? ? ? ? ? ? ? ? 3: "Plastic 1",
? ? ? ? ? ? ? ? ? ? 4: "Plastic 2",
? ? ? ? ? ? ? ? ? ? 5: "Plastic 3",
? ? ? ? ? ? ? ? ? ? 6: "Metal 1",
? ? ? ? ? ? ? ? ? ? 7: "Metal 2"}
? ? ? ? edge_weights = [1, 0.5, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1]? # ?????? ? ? ? ? ? ?
? ? ? ? new_edge_weights = [ int(x*10) for x in edge_weights]
? ? ? ? lengths = {}
? ? ? ? for e,l in zip(edges, new_edge_weights):
? ? ? ? ? ? lengths[e] = dict(len=l)
? ? ? ? ? ??
? ? ? ? G.add_nodes_from(nodes)
? ? ? ? G.add_edges_from(edges)
? ? ? ? nx.set_edge_attributes(G, lengths)
??
? ? ? ? pos = graphviz_layout(G, prog='neato')
? ? ? ? # Set the nodel label to empty for the new node
? ? ? ? node_label[len(node_label)+1] = ""?
? ? ? ? # Set the size of the new node smaller than the master node
? ? ? ? master_idx = 0
? ? ? ? node_sizes.append(node_sizes[master_idx]-300)
? ? ? ? # change the master node color to black
? ? ? ? node_color[master_idx] = "#000000"
? ? ? ? # set the color of the inner node (new smaller node)
? ? ? ? node_color.append("#00d992")
? ? ? ? # Set the position of the node same as the master node
? ? ? ? pos[len(pos)+1] = pos[master_idx]
? ? ? ? # Add node to the graph
? ? ? ? G.add_node(len(node_label))
? ? ? ? # Draw the graph
? ? ? ? nx.draw_networkx(G,
? ? ? ? ? ? pos=pos,
? ? ? ? ? ? node_size = node_sizes,
? ? ? ? ? ? node_color = node_color,
? ? ? ? ? ? edge_weights='len',
? ? ? ? ? ? labels = node_label,
? ? ? ? ? ? with_labels=True)
? ? ? ? self.vbox = wx.BoxSizer(wx.VERTICAL)
? ? ? ? self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
? ? ? ? self.panel.SetSizer(self.vbox)
if __name__ == '__main__':
? app = wx.App()
? app.frame = NetworkFrame()
? app.frame.Show()
? app.MainLoop()

TA貢獻2021條經驗 獲得超8個贊
add_weighted_edges_from代替使用add_edges_from
import wx
import matplotlib.pyplot as plt
import networkx as nx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
class NetworkFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1)
self.SetSize(wx.Size(1280, 768))
self.panel = wx.Panel(self)
self.fig = plt.figure()
self.canvas = FigCanvas(self.panel, -1, self.fig)
G = nx.Graph()
nodes = [0, 1, 2, 3, 4, 5, 6, 7]
node_sizes = [6500, 4000, 4000, 2500, 2500, 2500, 2500, 2500]
node_color = ["#00d992", "#00d9c8", "#00d9c8", "#00b4d9", "#00b4d9", "#00b4d9", "#00b4d9", "#00b4d9"]
edges = [(1, 0, 1), (2, 0, 0.5), (3, 1, 0.1), (4, 1, 0.1), (5, 1, 0.1), (6, 2, 0.1), (7, 2, 0.1)]
node_label = {0: "Printer",
1: "Case",
2: "Electronics",
3: "Plastic 1",
4: "Plastic 2",
5: "Plastic 3",
6: "Metal 1",
7: "Metal 2"}
G.add_nodes_from(nodes)
G.add_weighted_edges_from(edges)
nx.draw(G, node_size=node_sizes, node_color=node_color, labels=node_label, with_labels=True)
plt.axis('off')
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
self.panel.SetSizer(self.vbox)
if __name__ == '__main__':
app = wx.App()
app.frame = NetworkFrame()
app.frame.Show()
app.MainLoop()
添加回答
舉報