首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >流程图(二)利用python绘制网络图

流程图(二)利用python绘制网络图

作者头像
HsuHeinrich
发布2024-12-24 13:38:46
发布2024-12-24 13:38:46
7080
举报
文章被收录于专栏:HsuHeinrichHsuHeinrich

流程图(二)利用python绘制网络图

网络图(Network chart)简介

网络图使用节点和连接线来显示事物之间的连接关系,用于说明实体之间的关系。一般分为定向网络图和非定向网络图。

快速绘制

基于pyecharts

代码语言:javascript
复制
from pyecharts import options as opts
from pyecharts.charts import Graph

nodes = [
    {"name": "结点1", "symbolSize": 10},
    {"name": "结点2", "symbolSize": 20},
    {"name": "结点3", "symbolSize": 30},
    {"name": "结点4", "symbolSize": 40},
    {"name": "结点5", "symbolSize": 50},
    {"name": "结点6", "symbolSize": 40},
    {"name": "结点7", "symbolSize": 30},
    {"name": "结点8", "symbolSize": 20},
]
links = []
for i in nodes:
    for j in nodes:
        links.append({"source": i.get("name"), "target": j.get("name")})
c = (
    Graph()
    .add("", nodes, links, repulsion=8000)
    .set_global_opts(title_opts=opts.TitleOpts(title="基本网络图"))
)

c.render_notebook()

基于networkx

代码语言:javascript
复制
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
 
# 自定义数据
df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']})
 
# 构造网络图数据格式
G=nx.from_pandas_edgelist(df, 'from', 'to')
 
# 绘制网络图
nx.draw(G, with_labels=True)
plt.show()

定制多样化的网络图

自定义网络图一般是结合使用场景对相关参数进行修改,并辅以其他的绘图知识。参数信息可以通过官网进行查看,其他的绘图知识则更多来源于实战经验,大家不妨将接下来的绘图作为一种学习经验,以便于日后总结。

通过pyecharts绘制多样化的网络图

点线网络

代码语言:javascript
复制
import requests
import json
from pyecharts import options as opts
from pyecharts.charts import Graph

# 获取官方的数据
url = "https://raw.githubusercontent.com/pyecharts/pyecharts-gallery/master/Graph/weibo.json"

response = requests.get(url)
j = json.loads(response.text)
nodes, links, categories, cont, mid, userl = j

c = (
    Graph()
    .add(
        "",
        nodes,
        links,
        categories,
        repulsion=50,
        linestyle_opts=opts.LineStyleOpts(curve=0.2),
        label_opts=opts.LabelOpts(is_show=False),
    )
    .set_global_opts(
        legend_opts=opts.LegendOpts(is_show=False),
        title_opts=opts.TitleOpts(title="微博转发关系网络"),
    )
)

c.render_notebook()

球状网络

代码语言:javascript
复制
import pyecharts.options as opts
from pyecharts.charts import Graph

# 获取官方的数据
url = 'https://echarts.apache.org/examples/data/asset/data/npmdepgraph.min10.json'
response = requests.get(url)
data = response.json()  # 将响应内容解析为JSON

nodes = [
    {
        "x": node["x"],
        "y": node["y"],
        "id": node["id"],
        "name": node["label"],
        "symbolSize": node["size"],
        "itemStyle": {"normal": {"color": node["color"]}},
    }
    for node in data["nodes"]
]

edges = [
    {"source": edge["sourceID"], "target": edge["targetID"]} for edge in data["edges"]
]


c = (
    Graph()
    .add(
        series_name="",
        nodes=nodes,
        links=edges,
        layout="none",
        is_roam=True,
        is_focusnode=True,
        label_opts=opts.LabelOpts(is_show=False),
        linestyle_opts=opts.LineStyleOpts(width=0.5, curve=0.3, opacity=0.7),
    )
    .set_global_opts(title_opts=opts.TitleOpts(title="NPM Dependencies网络"))
)

c.render_notebook()

通过networkx绘制多样化的网络图

更多用法可参考:Networkx Tutorial[1]

修改参数

代码语言:javascript
复制
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib as mpl
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签

# 初始化布局
fig = plt.figure(figsize=(16,8))
 
# 自定义数据
df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']})
 
# 构造网络图数据格式
G=nx.from_pandas_edgelist(df, 'from', 'to')

# 自定义参数
plt.subplot(2, 4, 1) 
nx.draw(G, with_labels=True, node_size=1500, node_color="skyblue", node_shape="o", alpha=0.5, linewidths=4, font_size=25, 
        font_color="grey", font_weight="bold", width=2, edge_color="grey")
plt.title('自定义参数')


# 自定义布局-fruchterman_reingold
plt.subplot(2, 4, 2) 
nx.draw(G, with_labels=True, node_size=1500, node_color="skyblue", pos=nx.fruchterman_reingold_layout(G))
plt.title('自定义布局-fruchterman_reingold')

# 自定义布局-circular
plt.subplot(2, 4, 3) 
nx.draw(G, with_labels=True, node_size=1500, node_color="skyblue", pos=nx.circular_layout(G))
plt.title('自定义布局-circular')

# 自定义布局-random
plt.subplot(2, 4, 4) 
nx.draw(G, with_labels=True, node_size=1500, node_color="skyblue", pos=nx.random_layout(G))
plt.title('自定义布局-random')

# 自定义布局-spectral
plt.subplot(2, 4, 5) 
nx.draw(G, with_labels=True, node_size=1500, node_color="skyblue", pos=nx.spectral_layout(G))
plt.title('自定义布局-spectral')

# 自定义布局-spring
plt.subplot(2, 4, 6) 
nx.draw(G, with_labels=True, node_size=1500, node_color="skyblue", pos=nx.spring_layout(G))
plt.title('自定义布局-spring')

# 有向网络
plt.subplot(2, 4, 7) 
GD=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.DiGraph() )
nx.draw(GD, with_labels=True, node_size=1500, alpha=0.3, arrows=True)
plt.title('有向网络')

# 无向网络
plt.subplot(2, 4, 8) 
GUD=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph() )
nx.draw(GUD, with_labels=True, node_size=1500, alpha=0.3, arrows=True)
plt.title('无向网络')


plt.show()

颜色映射

代码语言:javascript
复制
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib as mpl
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签

# 自定义数据
df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 
                   'to':['D', 'A', 'E','C'], 
                   'value1':[1, 10, 5, 5],
                   'value2':['typeA', 'typeA', 'typeB', 'typeB']
                  })
# 具有节点特征的数据1-连续颜色分配
carac1 = pd.DataFrame({ 'ID':['A', 'B', 'C','D','E'], 'myvalue':['123','25','76','12','34'] })
# 具有节点特征的数据2-离散颜色分配
carac2 = pd.DataFrame({ 'ID':['A', 'B', 'C','D','E'], 'myvalue':['group1','group1','group2','group3','group3'] })
# 构造网络图数据格式
G=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph() )
# 利用节点顺序排序carac1
carac1 = carac1.set_index('ID')
carac1 = carac1.reindex(G.nodes())
# 利用节点顺序排序carac2,并转化为Categorical编码
carac2 = carac2.set_index('ID')
carac2 = carac2.reindex(G.nodes())
carac2['myvalue']=pd.Categorical(carac2['myvalue'])
carac2['myvalue'].cat.codes
# 将value2化为Categorical编码
df['value2']=pd.Categorical(df['value2'])
df['value2'].cat.codes

# 初始化布局
fig = plt.figure(figsize=(16,8))

# 将连续颜色映射到节点
plt.subplot(2, 2, 1) 
nx.draw(G, with_labels=True, node_color=carac1['myvalue'].astype(int), cmap=plt.cm.Blues)
plt.title('将连续颜色映射到节点')

# 将离散颜色映射到节点
plt.subplot(2, 2, 2) 
nx.draw(G, with_labels=True, node_color=carac2['myvalue'].cat.codes, cmap=plt.cm.Set1, node_size=1500)
plt.title('将离散颜色映射到节点')

# 将连续颜色映射到边线
plt.subplot(2, 2, 3) 
nx.draw(G, with_labels=True, node_color='skyblue', node_size=1500, edge_color=df['value1'], width=10.0, edge_cmap=plt.cm.Blues)
plt.title('将连续颜色映射到边线')

# 将离散颜色映射到边线
plt.subplot(2, 2, 4) 
nx.draw(G, with_labels=True, node_color='skyblue', node_size=1500, edge_color=df['value2'].cat.codes, width=10.0, edge_cmap=plt.cm.Set2)
plt.title('将离散颜色映射到边线')



plt.show()

基于相关矩阵的网络图

代码语言:javascript
复制
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
 
# 自定义数据
ind1=[5,10,3,4,8,10,12,1,9,4]
ind5=[1,1,13,4,18,5,2,11,3,8]
df = pd.DataFrame({ 'A':ind1,
                   'B':ind1 + np.random.randint(10, size=(10)) , 
                   'C':ind1 + np.random.randint(10, size=(10)) , 
                   'D':ind1 + np.random.randint(5, size=(10)) , 
                   'E':ind1 + np.random.randint(5, size=(10)), 
                   'F':ind5, 
                   'G':ind5 + np.random.randint(5, size=(10)) , 
                   'H':ind5 + np.random.randint(5, size=(10)), 
                   'I':ind5 + np.random.randint(5, size=(10)), 
                   'J':ind5 + np.random.randint(5, size=(10))})
 
# 计算相关性
corr = df.corr()
 
# 转化为长格式
links = corr.stack().reset_index()
links.columns = ['var1', 'var2', 'value']
 
# 过滤数据,仅保留高相关性,并删除自相关
links_filtered=links.loc[ (links['value'] > 0.8) & (links['var1'] != links['var2']) ]
 
# 构造网络图数据格式
G=nx.from_pandas_edgelist(links_filtered, 'var1', 'var2')
 
# 绘制相关矩阵网络图
nx.draw(G, with_labels=True, node_color='orange', node_size=400, edge_color='black', linewidths=1, font_size=15)

plt.show()

拓展-绘制具有边缘捆绑的网络图

代码语言:javascript
复制
%%capture --no-display
# 上述代码隐藏警告信息输出

import matplotlib.pyplot as plt
import networkx as nx
from netgraph import Graph

# 自定义数据
partition_sizes = [10, 20, 30, 40]
g = nx.random_partition_graph(partition_sizes, 0.5, 0.1)


# 将数据按照partition_sizes分为4类
node_to_community = dict()
node = 0
for community_id, size in enumerate(partition_sizes):
    for _ in range(size):
        node_to_community[node] = community_id
        node += 1

# 针对各类自定义颜色
community_to_color = {
    0 : 'tab:blue',
    1 : 'tab:orange',
    2 : 'tab:green',
    3 : 'tab:red',
}
node_color = {node: community_to_color[community_id] \
              for node, community_id in node_to_community.items()}


fig, ax = plt.subplots()
Graph(g,
      node_color=node_color, # 节点颜色
      node_edge_width=0,     # 去除节点边缘的边框
      edge_width=0.1,        # 边缘宽度
      edge_alpha=0.5,        # 边缘透明度
      node_layout='community', node_layout_kwargs=dict(node_to_community=node_to_community),
      edge_layout='bundled', # 带捆绑的束
      ax=ax,
)
plt.show()

总结

以上通过pyecharts和networkx快速绘网络图。并通过修改参数或者辅以其他绘图知识自定义各种各样的网络图来适应相关使用场景。

共勉~

参考资料

[1]

Networkx Tutorial:https://networkx.org/documentation/stable/tutorial.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 HsuHeinrich 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 流程图(二)利用python绘制网络图
    • 网络图(Network chart)简介
    • 快速绘制
    • 定制多样化的网络图
      • 通过pyecharts绘制多样化的网络图
      • 通过networkx绘制多样化的网络图
    • 总结
      • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档