首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >网络可视化,如何对齐节点,绘制更简单的图形?

网络可视化,如何对齐节点,绘制更简单的图形?
EN

Stack Overflow用户
提问于 2021-06-08 12:56:21
回答 1查看 603关注 0票数 3

我一直致力于可视化应用程序类型之间的关系。这不是一个确切的‘网络’,但我想画一个网络图。

每个流派有32种类型,每种流派之间的关系如下所示:

代码语言:javascript
复制
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!)阴谋还不清楚。

代码语言:javascript
复制
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")

代码语言:javascript
复制
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)

我想清楚地看到节点之间的有向关系(,权重有多大)。

如果我能得到一个看起来像

或者至少

像这样有更好的澄清。

如果有人能帮我解决这个问题,我将不胜感激。谢谢,提前!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-08 16:34:20

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

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

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

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

代码语言:javascript
复制
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')
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67887421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档