如何改善网络图的可视化? [英] How to improve network graph visualization?

查看:205
本文介绍了如何改善网络图的可视化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在python中使用networkx将相邻矩阵转换为图形. 我的加权"图大约有8000个节点和14000个边. 是否有很棒的布局图或其他软件包,工具可以使我的图形变得更漂亮? 我希望结果是,边缘权重越高,节点越近. 这样我就可以分析群集节点了.

I tried to use networkx in python to turn an adjacent matrix into a graph. My "weighted" graph has about 8000 nodes and 14000 edges. Is there a great layout form or other packages, tools to make my graph become more beautiful? I hope the outcome is that the edge weight higher the nodes become closer. So that I could analyze the cluster nodes.

我已经尝试了networkx文档中提供的所有布局. 我也尝试使用gephi,但仍然对我的理想不满意. 这是在networkx中的外观.它可以显示所有群集,但对于患有强烈恐惧症的人来说,这看起来有点可怕:

I had tried all the layout provided in networkx document. I also tried to use gephi and it still a little bit not satisfied with my ideal. This is how it look in networkx. It can show out all the cluster but it looks a little bit terrible for someone who has Intensive phobia:

这是我用来绘制图形的代码:

Here is the code I used to draw the graph:

G = nx.Graph()
for i in range(10000):
    for j in range(10000):
        if mat[i][j] > 10:
            G.add_edge(a[i], a[j], weight=mat[i][j])
pos = nx.nx_pydot.graphviz_layout(G)
plt.figure(figsize=(8, 8))
plt.axis('off')
nx.draw_networkx(G, pos=pos, with_labels=False, node_size=25, edgecolors='black', edge_color='b')
plt.show()

推荐答案

让我们深入研究大型图形可视化:

在您的问题中,您可以通过三种方式来可视化图形:

Let's dive a bit into large graph visualization:

In the context of your question you have three ways to visualize a graph:

  1. 在一个屏幕上绘制整个图形
  2. 在大于一个屏幕的表面上绘制图形
  3. 部分绘制图形或减少绘制元素的数量

我们将一一回顾这些方式:

We will review these ways one by one:

图形中有8000个节点和14000个边.假设您只需要绘制没有边缘的节点.因此,对于普通的FullHD显示器,您将拥有:

You have 8000 nodes and 14000 edges in your graph. Let's imagine that you only need to draw nodes without edges. So for an average FullHD display you will have:

1920 * 1080 / 8000 = 259像素.它是:

sqrt(259) = 17

17×17像素.节点,如果您将整个显示与节点平铺.如果要绘制节点标签,则将具有:

A 17×17 px. node if you will tile the whole display with nodes. If you want to draw node labels, you will have:

17 - 1 * 2 (outer node borders) - 1 * 2 (inner node borders) = 13×13正方形.可能的最小字体(我不会谈论深奥的字体)的大小为3×3(+1),因此您可以每个节点最多可存储9个字符.

17 - 1 * 2 (outer node borders) - 1 * 2 (inner node borders) = 13×13 square. The smallest possible font (I will not talk about esoteric fonts) has 3×3(+1) size so you can store no more than 9 characters per node.

它看起来像这样:

我们还没有绘制图形边缘!如果要这样做,我们将使用:

And we still haven't drawn graph edges! If we want to do it, we will use:

1920 * 1080 / (8000 + 14000) = 94像素,并且:

sqrt(94) = 9.7-9×9像素.节点,因此几乎不可能在其上贴上简单的标签.

sqrt(94) = 9.7 - 9×9 px. nodes so it is nearly impossible to have even simple labels on them.

我认为现在很明显,单个屏幕上的整个图形看起来总是像一团糟.因此,以这种方式绘制图形不是一种选择.

I think it is obvious now that the whole graph on the single screen will always be looking like a horrifying mess. So it's not an option to draw your graph this way.

如果我们不能在一个屏幕上绘制图形,那么我们可以动脑筋并发明一种解决方法-在多个屏幕上绘制图形!我们可以通过两种方式做到这一点:

If we can't draw the graph on one screen, we can rake our brains and invent a way out - to draw it on several screens! We can do it two ways:

  • 使用matplotlib
  • 使用graphviz

在matplotlib的情况下,我们创建了一个非常大的图形(带有figsize参数),然后将图形导入到图片中(具有plt.savefig):

In matplotlib case we create a very large figure (with figsize argument) and then import our graph to a picture (with plt.savefig):

import networkx as nx 
import matplotlib.pyplot as plt 

fig = plt.figure(figsize=(40, 40)) 
G = nx.fast_gnp_random_graph(300, 0.02, seed=1337) 
nx.draw(G, node_size=30) 
plt.axis('equal') 
plt.show() 
fig.savefig('waka.svg') 

因此,我们将获得一个很大的矢量图片(这只是其中的一小部分):

So we will have a big vector picture (here is a small part of it):

在这种情况下,我们可以使用networkx中可用的任何图形布局.

In this case we can use any graph layout available in networkx.

另一种方法是使用Graphviz外部库来绘制我们的图形.老实说,在这种情况下,networkx只会将图形转换为.dot文件并将其发送给Graphviz.主要缺点是您无法控制Graphviz如何绘制图形.但是它的布局非常好,因此结果可以接受.

Another way is to use Graphviz external library that will draw our graph. Honestly, in this case networkx will just convert the graph to .dot file and send it to Graphviz. The main disadvantage is that you can't control how Graphviz will draw your graph. But it has pretty good layouts so the result will be acceptable.

使用以下Python代码生成.dot文件:

Use this Python code to generate .dot file:

import networkx as nx 

G = nx.fast_gnp_random_graph(300, 0.02, seed=1337) 
nx.nx_agraph.write_dot(G, './waka.dot')

然后使用Graphviz:

and then use Graphviz:

dot -Tsvg waka.dot >waka.svg

或对于无向图:

neato -Tsvg waka.dot -Goverlap=false >waka.svg

所以结果图片看起来像这样(这也是整个图片的一小部分):

so the result picture will be looking like this (here is a small part of the whole picture too):

Graphviz有大量的各种选项,因此您可以按自己的意愿变换图形.

Graphviz has the huge amount of various options so you can transform your graph looking nearly as you wish.

在您的图形中,您会看到一些类似巨大的连接组件( GCC )和许多小子图.整个图片约为580×580尺寸,GCC约为290×290尺寸,因此GCC使用:

In your graph you have something like a giant connected component ( GCC ) and many small subgraphs. The whole picture is about 580×580 size and GCC is about 290×290 size so GCC uses:

(290 × 290) ÷ (580 × 580) × 100 = 25%.如果仅保留GCC,您将有4倍的绘制空间!在这种情况下,您可以在另一张图像上绘制另一个连接的组件.

(290 × 290) ÷ (580 × 580) × 100 = 25% of your canvas. If you will keep only GCC, you will have 4 times more space to draw! In this case you can draw another connected components on another image.

您只能使用以下代码保留GCC:

You can keep only GCC with code like this:

import networkx as nx 

G = nx.fast_gnp_random_graph(300, 0.01, seed=1337)
gcc = max(nx.connected_components(G), key=lambda x: len(x))
H = G.subgraph(gcc)
nx.draw(G, node_size=30, node_color='red')

将绘制原始图形:

最后一行:

nx.draw(H, node_size=30, node_color='red')

它将仅绘制GCC:

您还可以尝试使用图形做什么?

What else you can try to do with your graph:

  • 集群化节点
  • 播放节点大小(PageRank等)
  • 玩边缘颜色
  • 不要画边,但要保持布局
  • WEEP(以防我的回答对您没有帮助)
  • Clusterize nodes
  • Play with node size (PageRank etc)
  • Play with edge color
  • Don't draw edges but keep the layout
  • WEEP (in case my answer didn't help you even a bit)

这篇关于如何改善网络图的可视化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆