如何解决从 Pandas 数据帧创建 Networkx 有向图时如何创建多线节点标签
我的问题是我的previous question的延续。
我正在尝试从 Pandas 数据帧创建 networkx 流程图。数据框记录订单如何流经多家公司。数据框中的大多数行都是连接的,并且连接表现在多列中。样本数据如下:
df = pd.DataFrame({'Company': ['A','A','B','C','C'],'event_type':['new','route','receive','execute','execute'],'event_id': ['110','120','200','210','220','300','310'],'prior_event_id': [np.nan,'110',np.nan,'300'],'route_id': [np.nan,'foo','bar',np.nan]}
)
数据框如下所示:
Company event_type event_id prior_event_id route_id
0 A new 110 NaN NaN
1 A route 120 110 foo
2 B receive 200 NaN foo
3 B execute 210 120 NaN
4 B route 220 210 bar
5 C receive 300 NaN bar
6 C execute 310 300 NaN
我能够使用以下代码从示例数据创建源列和目标列:
df['event_sub'] = df.groupby([df.Company,df.event_type]).cumcount()+1
df['event'] = df.Company + ' ' + df.event_type + ' ' + df.event_sub.astype(str)
replace_dict_event = dict(df[['event_id','event']].values)
df['source'] = df['prior_event_id'].apply(lambda x: replace_dict_event.get(x) if replace_dict_event.get(x) else np.nan )
df['target'] = df['event_id'].apply(lambda x: replace_dict_event.get(x) if replace_dict_event.get(x) else np.nan )
replace_dict_rtd = dict(df[df.event_type == 'route'][['route_id','event']].values)
df.loc[df.event_type == 'receive','source'] = df[df.event_type == 'receive']['route_id'].apply(lambda x: replace_dict_rtd.get(x))
现在数据框看起来像这样:
上面的结果与我之前问题中的结果之间的细微差别是我在当前结果中加入了公司名称。我从 source
和 target
列创建的 networkx 图如下所示:
但是,我面临的问题是,在我的实际数据中,公司名称更长,节点更多。因此,很多时候标签都被挤在一起,基本上变得难以理解。我想到的第一个解决方案是将标签分成多行。我想要的节点如下所示:
我尝试的是在相关列中添加“\n”,因此我将最后一个代码块的第二行更改为
df['event'] = df.Company + '\n' + df.event_type + ' ' + df.event_sub.astype(str)
但这并没有给我想要的。相反,我得到了“KeyError: 'Node A\nnew 1 not in graph.'”我尝试了一些我在 SO 上找到的其他方法,但也没有运气。
有什么办法可以实现吗?
解决方法
# dummy data
a = np.random.randint(0,2,size=(10,10))
G = nx.from_numpy_matrix(a)
pos = nx.spring_layout(G)
# draw without labels,then draw labels separately
nx.draw_networkx(G,pos=pos,with_labels=False)
# draw_networkx_labels takes as keyword argument a dictionary called labels
# which links the id of a node to a name.
# you can create one using dictionary comprehension like so:
nodenames = {n:'firstline \n secondline \n thirdline' for n in G.nodes()}
# and then draw:
nx.draw_networkx_labels(G,labels=nodenames);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。