Python使用Networkx實(shí)現(xiàn)復(fù)雜的人物關(guān)系圖
1 簡單引入
- 日常工作、生活中我們經(jīng)常會(huì)遇到一些復(fù)雜的事務(wù)關(guān)系,比如人物關(guān)系,那如何才能清楚直觀的看清楚這些任務(wù)關(guān)系呢?
- 比如我們從網(wǎng)上搜索1個(gè)人物關(guān)系圖,大家看看:
聲明:以下圖片來源于網(wǎng)絡(luò),如果涉及版權(quán)問題,請聯(lián)系作者刪除。本文僅供學(xué)習(xí),不做他用。

- 那我們?nèi)绾问褂?code>Python來實(shí)現(xiàn)類似的人物關(guān)系圖呢?
- 這里我們需要用到Python的
networkx模塊,它可以幫助我們很好的顯示我們需要的效果。
2 關(guān)于Networkx
2.1 Networkx簡單說明
NetworkX是一個(gè)用于創(chuàng)建、操作和研究復(fù)雜網(wǎng)絡(luò)的Python庫;- 可以創(chuàng)建、分析和可視化各種類型的網(wǎng)絡(luò),例如社交網(wǎng)絡(luò)、Web圖、生物網(wǎng)絡(luò)等;
NetworkX可以用來創(chuàng)建各種類型的網(wǎng)絡(luò),包括有向圖和無向圖;- 提供各種方法來添加、刪除和修改網(wǎng)絡(luò)中的節(jié)點(diǎn)和邊;
NetworkX還提供許多圖的算法和分析工具;NetworkX還提供多種方式來可視化網(wǎng)絡(luò)。
2.2 Networkx部分源碼
NetworkX支持四種圖,從以下源碼可以看出:
Python37\Lib\site-packages\networkx\classes\__init__.py
from .graph import Graph from .digraph import DiGraph from .multigraph import MultiGraph from .multidigraph import MultiDiGraph from .ordered import * from .function import * from networkx.classes import filters from networkx.classes import coreviews from networkx.classes import graphviews from networkx.classes import reportviews
- 四種圖即為:
| 圖 | 說明 |
|---|---|
Graph | 無多重邊無向圖 |
DiGraph | 無多重邊有向圖 |
MultiGraph | 有多重邊無向圖 |
MultiDiGraph | 有多重邊有向圖 |
- 而本文我們要用的是
Graph,它主要是用點(diǎn)和線來刻畫離散事務(wù)集合,每對事務(wù)之間以某種方式相聯(lián)系的數(shù)學(xué)模型; Graph可以用來表示的關(guān)系圖為人物關(guān)系圖、流程圖等等;- 以下為
Graph的幾個(gè)方法源碼:
Python37\Lib\site-packages\networkx\classes\graph.py
def draw_networkx_nodes(
G,
pos,
nodelist=None,
node_size=300,
node_color="#1f78b4",
node_shape="o",
alpha=None,
cmap=None,
vmin=None,
vmax=None,
ax=None,
linewidths=None,
edgecolors=None,
label=None,
margins=None,
):
"""Draw the nodes of the graph G.
def draw_networkx_edges(
G,
pos,
edgelist=None,
width=1.0,
edge_color="k",
style="solid",
alpha=None,
arrowstyle="-|>",
arrowsize=10,
edge_cmap=None,
edge_vmin=None,
edge_vmax=None,
ax=None,
arrows=None,
label=None,
node_size=300,
nodelist=None,
node_shape="o",
connectionstyle="arc3",
min_source_margin=0,
min_target_margin=0,
):
r"""Draw the edges of the graph G.
def draw_networkx_labels(
G,
pos,
labels=None,
font_size=12,
font_color="k",
font_family="sans-serif",
font_weight="normal",
alpha=None,
bbox=None,
horizontalalignment="center",
verticalalignment="center",
ax=None,
clip_on=True,
):
"""Draw node labels on the graph G.
def circular_layout(G, scale=1, center=None, dim=2):
# dim=2 only
"""Position nodes on a circle.
Parameters
----------
G : NetworkX graph or list of nodes
A position will be assigned to every node in G.
scale : number (default: 1)
Scale factor for positions.
center : array-like or None
Coordinate pair around which to center the layout.
dim : int
Dimension of layout.
If dim>2, the remaining dimensions are set to zero
in the returned positions.
If dim<2, a ValueError is raised.
2.3 Networkx一個(gè)示例
- 比如一個(gè)幾個(gè)節(jié)點(diǎn)的有向圖:
# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt
# 設(shè)置畫布大小
plt.figure(figsize=(6, 7))
# 創(chuàng)建有向圖對象
G = nx.DiGraph()
# 添加節(jié)點(diǎn)
my_node = ["nodeA", "nodeB", "nodeC", "nodeD", "nodeE", "nodeF"]
for node in my_node:
G.add_node(node)
# 添加有向邊
for edge in range(len(my_node)-1):
print(edge)
G.add_edge(my_node[edge], my_node[edge+1])
# 繪制
# 布局算法
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True)
plt.show()
輸出如下圖示:

3 人物關(guān)系圖繪制過程
3.1 創(chuàng)建原始數(shù)據(jù)
- 我們以西游記和封神榜部分重點(diǎn)人物關(guān)系為例,先整理好一個(gè)任務(wù)關(guān)系
excel文檔relation.xls:
character1 character2 color num relation 菩提祖師 孫悟空 antiquewhite 9 第一任師傅 唐僧 孫悟空 aqua 9 師徒 如來佛祖 孫悟空 aquamarine 9 五指山 觀音菩薩 孫悟空 azure 9 緊箍咒 牛魔王 孫悟空 beige 9 結(jié)拜兄弟 豬八戒 孫悟空 bisque 9 大師兄 沙和尚 孫悟空 black 9 大師兄 白龍馬 孫悟空 blanchedalmond 9 大師兄 孫悟空 唐僧 aliceblue 6 師徒 豬八戒 唐僧 bisque 6 師徒 沙和尚 唐僧 black 6 師徒 白龍馬 唐僧 blanchedalmond 6 師徒 觀音菩薩 唐僧 azure 6 委派西天取經(jīng) 老鼠精 唐僧 blue 6 欲嫁 老鼠精 托塔天王 blue 4 義父女 哪吒 托塔天王 blueviolet 4 父子 木吒 托塔天王 brown 4 父子 金吒 托塔天王 burlywood 4 父子 木吒 觀音菩薩 brown 2 大弟子 紅孩兒 觀音菩薩 cadetblue 2 善財(cái)童子 金吒 如來佛祖 burlywood 1 前部護(hù)法 鐵扇公主 牛魔王 darkkhaki 2 夫妻 紅孩兒 牛魔王 cadetblue 2 父子 紅孩兒 鐵扇公主 cadetblue 1 母子 哪吒 太乙真人 blueviolet 1 師徒 太乙真人 元始天尊 chartreuse 7 師徒 云中子 元始天尊 chocolate 7 師徒 玉鼎真人 元始天尊 coral 7 師徒 王母娘娘 元始天尊 cornflowerblue 7 父女 鴻鈞老祖 元始天尊 cornsilk 7 師徒 姜子牙 元始天尊 crimson 7 師徒 太上老君 鴻鈞老祖 cyan 3 師徒 靈寶天尊 鴻鈞老祖 darkblue 3 師徒 雷震子 云中子 darkcyan 1 師徒 楊戩 玉鼎真人 darkgoldenrod 1 師徒 沉香 楊戩 darkgray 2 舅舅 三圣母 楊戩 darkgreen 2 兄妹 元始天尊 鴻鈞老祖 darkmagenta 3 師徒 托塔天王 孫悟空 darkgrey 9 上下級(jí)
- 這里需要注意一點(diǎn),人物的數(shù)量和顏色的數(shù)量要對應(yīng)起來,不然會(huì)報(bào)錯(cuò):
ValueError: 'c' argument has 23 elements, which is inconsistent with 'x' and 'y' with size 29.
- 從上邊的錯(cuò)誤看,其實(shí)就是我的人物角色有29個(gè),但是顏色只有23個(gè),沒有對應(yīng)起來;
- 為了避免錯(cuò)誤,我們把人物和顏色列一個(gè)表,需要的時(shí)候選對應(yīng)的數(shù)據(jù)就行:
孫悟空 aliceblue 菩提祖師 antiquewhite 唐僧 aqua 如來佛祖 aquamarine 觀音菩薩 azure 牛魔王 beige 豬八戒 bisque 沙和尚 black 白龍馬 blanchedalmond 老鼠精 blue 哪吒 blueviolet 木吒 brown 金吒 burlywood 紅孩兒 cadetblue 太乙真人 chartreuse 云中子 chocolate 玉鼎真人 coral 王母娘娘 cornflowerblue 鴻鈞老祖 cornsilk 姜子牙 crimson 太上老君 cyan 靈寶天尊 darkblue 雷震子 darkcyan 楊戩 darkgoldenrod 沉香 darkgray 三圣母 darkgreen 托塔天王 darkgrey 鐵扇公主 darkkhaki 元始天尊 darkmagenta
3.2 獲取目標(biāo)文件數(shù)據(jù)
- 讀取
excel中的文件數(shù)據(jù):
class TestRelation():
def __init__(self):
super(TestRelation, self).__init__()
# 獲取目標(biāo)文件數(shù)據(jù)
self.data = "./relation.xls"
self.data_content = pd.DataFrame(pd.read_excel(self.data))
self.character = self.data_content['character1'].drop_duplicates().values.tolist()
self.characters = self.data_content[['character1', 'character2', 'num']]
- 比如我們打印一下
self.characters:
0 菩提祖師 孫悟空 9 1 唐僧 孫悟空 9 2 如來佛祖 孫悟空 9 3 觀音菩薩 孫悟空 9 4 牛魔王 孫悟空 9 5 豬八戒 孫悟空 9 6 沙和尚 孫悟空 9 7 白龍馬 孫悟空 9 8 孫悟空 唐僧 6 9 豬八戒 唐僧 6 10 沙和尚 唐僧 6 11 白龍馬 唐僧 6 12 觀音菩薩 唐僧 6 13 老鼠精 唐僧 6 14 老鼠精 托塔天王 4 15 哪吒 托塔天王 4 16 木吒 托塔天王 4 17 金吒 托塔天王 4 18 木吒 觀音菩薩 2 19 紅孩兒 觀音菩薩 2 20 金吒 如來佛祖 1 21 鐵扇公主 牛魔王 2 22 紅孩兒 牛魔王 2 23 紅孩兒 鐵扇公主 1 24 哪吒 太乙真人 1 25 太乙真人 元始天尊 7 26 云中子 元始天尊 7 27 玉鼎真人 元始天尊 7 28 王母娘娘 元始天尊 7 29 鴻鈞老祖 元始天尊 7 30 姜子牙 元始天尊 7 31 太上老君 鴻鈞老祖 3 32 靈寶天尊 鴻鈞老祖 3 33 雷震子 云中子 1 34 楊戩 玉鼎真人 1 35 沉香 楊戩 2 36 三圣母 楊戩 2 37 元始天尊 鴻鈞老祖 3 38 托塔天王 孫悟空 9
3.3 獲取顏色數(shù)據(jù)
# 獲取顏色數(shù)據(jù) self.colors = self.data_content['color'].drop_duplicates().values.tolist() print(self.colors)
- 顏色獲取如下:
['antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'aliceblue', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'darkkhaki', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkmagenta', 'darkgrey']
3.5 添加邊數(shù)據(jù)
self.my_graph = nx.Graph()
for i in self.characters.index:
self.my_graph.add_edge(self.characters.character1[i],
self.characters.character2[i],
weight=self.characters.num[i])
3.6 定義邊及權(quán)重
# 定義兩個(gè)邊,邊給權(quán)重,s起點(diǎn),e終點(diǎn),w權(quán)重 edge1 = [(s, e) for (s, e, w) in self.my_graph.edges(data=True) if (w['weight'] >= 1)] edge2 = [(s, e) for (s, e, w) in self.my_graph.edges(data=True) if (w['weight'] >= 5)]
3.7 圖的布局、點(diǎn)、邊和標(biāo)簽
# 圖的布局
pos = nx.circular_layout(self.my_graph)
# 點(diǎn)
nx.draw_networkx_nodes(self.my_graph, pos, alpha=1, node_size=300,
node_color=self.colors, node_shape='o')
# 邊
nx.draw_networkx_edges(self.my_graph, pos, edgelist=edge1, width=1,
alpha=0.3, edge_color='g', style='dashed')
nx.draw_networkx_edges(self.my_graph, pos, edgelist=edge2, width=1.5,
alpha=0.5, edge_color='red')
# 標(biāo)簽
nx.draw_networkx_labels(self.my_graph, pos, font_size=9)
3.8 展示結(jié)果
# 結(jié)果顯示
plt.axis('off')
plt.title('西游記重點(diǎn)人物簡單關(guān)系圖(只是示例)')
plt.rcParams['font.size'] = 8
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.show()
3.9 完整源碼
# -*- coding:utf-8 -*-
# 作者:蟲無涯
# 日期:2023/11/16
# 文件名稱:test_relation.py
# 作用:network應(yīng)用
# 聯(lián)系:VX(NoamaNelson)
# 博客:https://blog.csdn.net/NoamaNelson
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
class TestRelation():
def __init__(self):
super(TestRelation, self).__init__()
# 獲取目標(biāo)文件數(shù)據(jù)
self.data = "./relation.xls"
self.data_content = pd.DataFrame(pd.read_excel(self.data))
self.character = self.data_content['character1'].drop_duplicates().values.tolist()
self.characters = self.data_content[['character1', 'character2', 'num']]
print(self.characters)
def test_relation(self):
# 設(shè)置畫布大小,可以使用默認(rèn)的
# plt.figure(figsize=(4, 5))
# 獲取顏色數(shù)據(jù)
self.colors = self.data_content['color'].drop_duplicates().values.tolist()
print(self.colors)
self.my_graph = nx.Graph()
# 添加邊
for i in self.characters.index:
self.my_graph.add_edge(self.characters.character1[i],
self.characters.character2[i],
weight=self.characters.num[i])
# 定義兩個(gè)邊,邊給權(quán)重,s起點(diǎn),e終點(diǎn),w權(quán)重
edge1 = [(s, e) for (s, e, w) in self.my_graph.edges(data=True) if (w['weight'] >= 1)]
edge2 = [(s, e) for (s, e, w) in self.my_graph.edges(data=True) if (w['weight'] >= 5)]
# 圖的布局
pos = nx.circular_layout(self.my_graph)
# 點(diǎn)
nx.draw_networkx_nodes(self.my_graph, pos, alpha=1, node_size=300,
node_color=self.colors, node_shape='o')
# 邊
nx.draw_networkx_edges(self.my_graph, pos, edgelist=edge1, width=1,
alpha=0.3, edge_color='g', style='dashed')
nx.draw_networkx_edges(self.my_graph, pos, edgelist=edge2, width=1.5,
alpha=0.5, edge_color='red')
# 標(biāo)簽
nx.draw_networkx_labels(self.my_graph, pos, font_size=9)
# 結(jié)果顯示
plt.axis('off')
plt.title('西游記重點(diǎn)人物簡單關(guān)系圖(只是示例)')
plt.rcParams['font.size'] = 8
plt.rcParams['font.sans-serif'] = ['SimHei'] # 解決中文亂碼
plt.show()
if __name__ == "__main__":
relation = TestRelation()
relation.test_relation()
4 人物關(guān)系效果圖
- 運(yùn)行上邊的完整源碼得到如下效果:

以上就是Python使用Networkx實(shí)現(xiàn)復(fù)雜的人物關(guān)系圖的詳細(xì)內(nèi)容,更多關(guān)于Python Networkx人物關(guān)系圖的資料請關(guān)注腳本之家其它相關(guān)文章!
- Python實(shí)現(xiàn)用networkx繪制MultiDiGraph
- Python中的Networkx的基本使用
- Python中卷積神經(jīng)網(wǎng)絡(luò)(CNN)入門教程分分享
- Python?CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)教程深入講解
- python機(jī)器學(xué)習(xí)GCN圖卷積神經(jīng)網(wǎng)絡(luò)原理解析
- python人工智能tensorflow構(gòu)建卷積神經(jīng)網(wǎng)絡(luò)CNN
- Python卷積神經(jīng)網(wǎng)絡(luò)圖片分類框架詳解分析
- python如何實(shí)現(xiàn)convolution neural network卷積神經(jīng)網(wǎng)絡(luò)算法
相關(guān)文章
python數(shù)學(xué)建模之Matplotlib?實(shí)現(xiàn)圖片繪制
這篇文章主要介紹了python數(shù)學(xué)建模之Matplotlib?實(shí)現(xiàn)圖片繪制,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07
python區(qū)塊鏈簡易版交易實(shí)現(xiàn)示例
這篇文章主要為大家介紹了python區(qū)塊鏈簡易版交易實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Python實(shí)現(xiàn)監(jiān)控屏幕界面內(nèi)容變化并發(fā)送通知
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)實(shí)時(shí)監(jiān)控屏幕上的信息是否發(fā)生變化并發(fā)送通知,文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-04-04
Python3.10耙梳加密算法Encryption種類及開發(fā)場景
這篇文章主要為大家介紹了Python3.10加密,各種加密,耙梳加密算法Encryption種類及開發(fā)場景運(yùn)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
pytorch 實(shí)現(xiàn)多個(gè)Dataloader同時(shí)訓(xùn)練
這篇文章主要介紹了pytorch 實(shí)現(xiàn)多個(gè)Dataloader同時(shí)訓(xùn)練的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05
PyTorch數(shù)據(jù)讀取的實(shí)現(xiàn)示例
這篇文章主要介紹了PyTorch數(shù)據(jù)讀取的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03

