【问题标题】:Network Visualization, How to align nodes and draw simpler graph?网络可视化,如何对齐节点并绘制更简单的图形?
【发布时间】:2021-06-08 12:56:21
【问题描述】:

我一直致力于可视化应用程序类型之间的关系。 它不完全是一个“网络”,但我想画一个网络图。

各有32个体裁,各体裁之间的关系表示如下:

genre_pt.most_common(20)

[(('Personalization', 'Communication'), 22274),
 (('Personalization', 'Social'), 9774),
 (('Communication', 'Personalization'), 8393),
 (('Communication', 'Communication'), 6244),
 (('Lifestyle', 'Health & Fitness'), 4142),
 (('Health & Fitness', 'Communication'), 3737),
 (('Tools', 'Communication'), 3584),
 (('Personalization', 'Tools'), 3082),
 (('Social', 'Personalization'), 2767),
 (('Personalization', 'Books & Reference'), 2662),
 (('Personalization', 'Health & Fitness'), 2548),
 (('Education', 'Communication'), 2530),
 (('Personalization', 'Education'), 2376),
 (('Social', 'Communication'), 2297),
 (('Personalization', 'Personalization'), 2285),
 (('Social', 'Health & Fitness'), 2261),
 (('Personalization', 'Finance'), 1985),
 (('Communication', 'Social'), 1926),
 (('Personalization', 'Lifestyle'), 1829),
 (('Communication', 'Tools'), 1729)]

我想做一个有向网络图,元组的第一个值表示节点从哪里来,下一个值表示节点到哪里,最后一个数值是两个节点之间的权重。

到目前为止,我已经设法通过以下代码使用 pyvis 或 networkx 进行绘图, 但由于我有太多节点(每个节点 32 个,所以 32*32 = 1024 !!)情节还不清楚。

net = Network(notebook=True)

for gen in set(genre_dict.values()): #add node
    net.add_node(gen, label=gen)

for k,v in zip(genre_pt.keys(), genre_pt.values()):
    if all(k) is False: continue
    net.add_edge(k[0], k[1], weight= v) #add values between nodes

ngx = nx.complete_graph(5)
net.from_nx(ngx)
net.show("example.html")

G = nx.DiGraph()

for k,v in zip(genre_pt.keys(), genre_pt.values()):
    G.add_edge(k[0], k[1], weight = v)

pos = nx.spring_layout(G)

nx.draw_networkx_nodes(G, pos, node_size=700)
edge_width = [0.15 * G[u][v]['weight'] for u, v in G.edges()]

graph = nx.draw_networkx(G,pos,
                 alpha = 0.7,
                 with_labels = True, width = edge_width,
                 edge_color ='.4', cmap = plt.cm.Blues)

我想看看有向关系(权重有多强) 节点之间以清晰的方式。

如果我能得到一个看起来像这样的图表,那将是最好的

至少

像这样,有更好的说明。

如果有人可以帮助我解决这个问题,我将不胜感激。 先感谢您! :D

【问题讨论】:

    标签: python networking visualization networkx


    【解决方案1】:

    这是一种解决方案。由于节点是相同的字符串,因此 networkx 将假定它们是相同的节点。我的解决方案是仅对节点使用整数,并仅通过字典映射在图中应用节点标签。然后我计算了一个自定义的职位字典。

    另外请注意,我将图重命名为 DG,因为这是有向图的命名约定。

    不幸的是,当绘制非常粗的线时,matplotlib 中的箭头看起来很奇怪,根据this SO question,我不确定除了手动调整一些相关参数之外可以做很多事情来修复它。

    首先是输出,然后是可复制粘贴的代码:

    import networkx as nx
    import matplotlib.pyplot as plt
    import numpy as np
    
    genre_pt = [(('Personalization', 'Communication'), 22274),
                (('Personalization', 'Social'), 9774),
                (('Communication', 'Personalization'), 8393),
                (('Communication', 'Communication'), 6244),
                (('Lifestyle', 'Health & Fitness'), 4142),
                (('Health & Fitness', 'Communication'), 3737),
                (('Tools', 'Communication'), 3584),
                (('Personalization', 'Tools'), 3082),
                (('Social', 'Personalization'), 2767),
                (('Personalization', 'Books & Reference'), 2662),
                (('Personalization', 'Health & Fitness'), 2548),
                (('Education', 'Communication'), 2530),
                (('Personalization', 'Education'), 2376),
                (('Social', 'Communication'), 2297),
                (('Personalization', 'Personalization'), 2285),
                (('Social', 'Health & Fitness'), 2261),
                (('Personalization', 'Finance'), 1985),
                (('Communication', 'Social'), 1926),
                (('Personalization', 'Lifestyle'), 1829),
                (('Communication', 'Tools'), 1729)]
    
    G1_keys = set([k[0] for k, _ in genre_pt])
    G2_keys = set([k[1] for k, _ in genre_pt])
    G_keys = G1_keys.union(G2_keys)
    num_keys = len(G_keys)
    G_mapping = {k: v for v, k in enumerate(G_keys)}
    G_rev_mapping = {k: v for k, v in enumerate(G_keys)}
    
    edge_list = []
    for edge, weight in genre_pt:
        mapped_edge = (G_mapping[edge[0]], G_mapping[edge[1]] + num_keys, weight)
        edge_list.append(mapped_edge)
    
    node_labels = {k: v for k, v in G_rev_mapping.items()}
    node_labels.update({k + num_keys: v for k, v in G_rev_mapping.items()})
    
    DG = nx.DiGraph()
    
    DG.add_weighted_edges_from(edge_list)
    DG.add_nodes_from([k for k in G_rev_mapping.keys()])
    
    pos = {}
    for node in node_labels.keys():
        x_spacing = np.linspace(-0.8, 0.8, num_keys)
        x = x_spacing[node] if node < num_keys else x_spacing[node - num_keys]
        y = 0.5 if node < num_keys else -0.5
        pos[node] = (x, y)
    
    edge_width = [DG[u][v]['weight'] for u, v in DG.edges()]
    normalized_edge_width = [10 * width / max(edge_width) for width in edge_width]
    
    plt.figure(1, figsize=(24, 8))
    graph = nx.draw_networkx(DG, pos,
                             alpha=0.7,
                             with_labels=True, width=normalized_edge_width,
                             edge_color='.4', cmap=plt.cm.Blues, node_size=4000, labels=node_labels,
                             arrowstyle='->,head_width=0.6,head_length=0.5')
    

    【讨论】:

    • 非常感谢!无论箭头看起来如何,它都是我想要绘制的确切图形。百万谢谢!!!!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2013-06-28
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 2012-11-26
    相关资源
    最近更新 更多