为了账号安全,请及时绑定邮箱和手机立即绑定

NetworkX 和 wxPython - 如何添加边权重?

NetworkX 和 wxPython - 如何添加边权重?

叮当猫咪 2023-05-09 16:03:43
我试图弄清楚如何向我的代码示例添加边缘权重,但我找不到任何与 wxPython 结合的好的文档。我想要边缘,可以说节点的距离就像我的列表“edge_weight”中的那样。标签和其他一切都按预期工作。作为一个小的补充,是否可以添加阴影效果或类似于主节点的任何东西来突出显示它?我的代码如下所示:import wximport matplotlib.pyplot as pltimport networkx as nxfrom matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvasclass 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),(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]  # ?????                             G.add_nodes_from(nodes)        G.add_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()
查看完整描述

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)

这是您的图形最终的样子:

//img3.sycdn.imooc.com/6459fe7f0001f62d06530387.jpg

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)

//img3.sycdn.imooc.com/6459fe8b00015b7206500386.jpg

请注意,我已缩放节点大小以使边缘可见。您可以根据您的要求更改它并相应地调整边缘长度。


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()



查看完整回答
反对 回复 2023-05-09
?
宝慕林4294392

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()



查看完整回答
反对 回复 2023-05-09
  • 2 回答
  • 0 关注
  • 212 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信