python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python Networkx人物关系图

Python使用Networkx实现复杂的人物关系图

作者:虫无涯

日常工作、生活中我们经常会遇到一些复杂的事务关系,比如人物关系,那如何才能清楚直观的看清楚这些任务关系呢?所以小编给大家介绍了Python如何使用Networkx实现复杂的人物关系图,文中通过代码示例讲解的非常详细,需要的朋友可以参考下

1 简单引入

声明:以下图片来源于网络,如果涉及版权问题,请联系作者删除。本文仅供学习,不做他用。

2 关于Networkx

2.1 Networkx简单说明

2.2 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有多重边有向图
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一个示例

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 设置画布大小
plt.figure(figsize=(6, 7))

# 创建有向图对象
G = nx.DiGraph()

# 添加节点
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 人物关系图绘制过程

3.1 创建原始数据

character1	character2	color	       num	 relation
菩提祖师	    孙悟空	    antiquewhite	9	  第一任师傅
唐僧	        孙悟空	    aqua	        9	  师徒
如来佛祖	    孙悟空	    aquamarine	    9	  五指山
观音菩萨	    孙悟空	    azure	        9	  紧箍咒
牛魔王	    孙悟空	    beige	        9	  结拜兄弟
猪八戒	    孙悟空	    bisque	        9	  大师兄
沙和尚	    孙悟空	    black	        9	  大师兄
白龙马	    孙悟空	    blanchedalmond	9	  大师兄
孙悟空	    唐僧	        aliceblue	    6	  师徒
猪八戒	    唐僧	        bisque	        6	  师徒
沙和尚	    唐僧	        black	        6	  师徒
白龙马	    唐僧	        blanchedalmond	6	  师徒
观音菩萨	    唐僧	        azure	        6	  委派西天取经
老鼠精	    唐僧	        blue	        6	  欲嫁
老鼠精	    托塔天王	    blue	        4	  义父女
哪吒	        托塔天王	    blueviolet	    4	  父子
木吒	        托塔天王	    brown	        4	  父子
金吒	        托塔天王	    burlywood	    4	  父子
木吒	        观音菩萨	    brown	        2	  大弟子
红孩儿	    观音菩萨	    cadetblue	    2	  善财童子
金吒	        如来佛祖	    burlywood	    1	  前部护法
铁扇公主	    牛魔王	    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	  上下级
ValueError: 'c' argument has 23 elements, which is inconsistent with 'x' and 'y' with size 29.
孙悟空	    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 获取目标文件数据

class TestRelation():
    def __init__(self):
        super(TestRelation, self).__init__()

        # 获取目标文件数据
        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']] 
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 获取颜色数据

# 获取颜色数据
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 添加边数据

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 定义边及权重

# 定义两个边,边给权重,s起点,e终点,w权重
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 图的布局、点、边和标签

# 图的布局
pos = nx.circular_layout(self.my_graph)

# 点
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')
# 标签
nx.draw_networkx_labels(self.my_graph, pos, font_size=9)

3.8 展示结果

# 结果显示
plt.axis('off')
plt.title('西游记重点人物简单关系图(只是示例)')
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应用
# 联系: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__()

        # 获取目标文件数据
        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):

        # 设置画布大小,可以使用默认的
        # plt.figure(figsize=(4, 5))

        # 获取颜色数据
        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])

        # 定义两个边,边给权重,s起点,e终点,w权重
        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)

        # 点
        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')
        # 标签
        nx.draw_networkx_labels(self.my_graph, pos, font_size=9)

        # 结果显示
        plt.axis('off')
        plt.title('西游记重点人物简单关系图(只是示例)')
        plt.rcParams['font.size'] = 8
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决中文乱码
        plt.show()


if __name__ == "__main__":
    relation = TestRelation()
    relation.test_relation()

4 人物关系效果图

以上就是Python使用Networkx实现复杂的人物关系图的详细内容,更多关于Python Networkx人物关系图的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文