我正在尝试找到一种正确的方法来绘制数据集的图形,该数据集包含有关用户通常在各个位置花费的时间量的信息。重要的是,有些类别和子类别的数据粒度越来越高(例如,60%的人在“家”,而其中40%的人在“客厅”)。我知道TreeMap可以显示所需的信息和关系,但是有人要求我对数据进行“网络”可视化。
我特别想寻找的是Python中的一种图形方法,该方法可以让我根据属于其类别的用户数量自动调整节点大小(更好的是,节点标签)来可视化我的数据。重要的是,所有子节点计数也将在父节点中计数(因此,树状图并不是真正的选择,因为我需要在每个分支点显示信息)。
我的数据看起来像这样(请注意,某些位置比其他位置更精细):
| ID | BUILDING | subcat01 | subcat02 |
----------------------------------------
| 00 | home | kitchen | fridge |
| 01 | office | desk | NaN |
| 02 | office | reception | NaN |
| 03 | home | bedroom | bed |
| 04 | home | yard | NaN |
| 05 | home | livingroom| couch |
| 06 | office | conf_room | NaN |
| 07 | outdoors | NaN | NaN |
|... | ... | ... | ... |
要大致了解我想要生产的产品,请参见下图。重要的是,我能够根据子节点的总和(或如果它们是末端节点,则仅根据子节点的总和)来调整节点的大小。我将使用不同的过滤器运行大量迭代,因此我需要可以轻松迭代的内容,而不仅仅是手动编码每个图形的外观。
关于哪个Python库可以最好地完成此工作的任何建议?我已经简要地研究了networkX,graph-tool和etetoolkit,但是不确定它们是否具有我所要查找的功能。
这是我想要产生的大致结果:
要生成图,可以将行设置为有向图的路径。一种简单的方法是定义一个 pandas 数据框并堆叠以删除丢失的值:
import networkx as nx
from networkx.drawing.nx_agraph import graphviz_layout
from pylab import rcParams
import pandas as pd
#df = pd.read_csv....
paths = df.loc[:,'BUILDING':].stack().groupby(level=0).agg(list).values.tolist()
# [['home', 'kitchen', 'fridge'], ['office', 'desk'], ['office', 'reception'],...
请注意,这里的堆栈很有用,因为它会忽略NaN,然后我们就可以gorupby
在索引上将其聚合为列表。然后创建一个有向图,并使用以下命令设置路径nx.add_path
:
G = nx.DiGraph()
for path in paths:
nx.add_path(G, path)
现在将图形可视化为树状布局,我们可以使用graphviz_layout
,它基本上是以下内容的包装器pygraphviz_layout
:
rcParams['figure.figsize'] = 14, 10
pos=graphviz_layout(G, prog='dot')
nx.draw(G, pos=pos,
node_color='lightgreen',
node_size=1500,
with_labels=True,
arrows=True)
如果你想添加一个共同的源节点的所有建筑物,你可以插入一个名为列ALL
右后ID
:
df.insert(1, 'ALL', 'ALL')
paths = df.loc[:,'ALL':].stack().groupby(level=0).agg(list).values.tolist()
然后按照上面的步骤进行操作,现在你将获得:
请注意,还有其他一些graphviz布局程序可能与你所想的更加相似。例如circo
:
pos=graphviz_layout(G, prog='circo')
nx.draw(G, pos=pos,
node_color='lightgreen',
node_size=1500,
with_labels=True,
arrows=True)
不错的解决方案,关于为每个级别添加描述的方式(“建筑物”,“ subcat1”等)有什么想法吗?