使用 graph_tool 绘制网络关系图

目标

使用pythongraph_tool包,根据以下表格,生成网络关系图。

采样方法 大类 小类
低空遥感解译 地面 裸土地,人工地面
地面影像解译 水生植物 水葫芦,荷叶,苦草,黑藻,水华,水白菜
RTK测量 禾本植物 狗牙根,华克拉莎,斑茅,苔草,芦苇,芦竹,杂茅
RTK测量 风箱树,马甲子
RTK测量 灌木 车筒竹,泰竹,凤尾竹
RTK测量 乔木 旱柳,垂柳,桂花,乌桕,樟树,枫香,银杏,桉树,楝,榆树
低空遥感解译 水稻 已收割,已焚烧,禾苗
低空遥感解译 菜地 铺草,菜苗
地面影像解译 景观树 景观乔木,景观灌木
低空遥感解译 人造物 房屋,木桥,,车辆

简介

Graph-tool 是一个高效的Python模块,用于图形 (又名网络)的操作和统计分析。 与大多数具有类似功能的其他 Python 模块相反,核心数据结构和算法是用C++实现的,广泛使用模板元编程,很大程度上基于Boost Graph Library。这赋予它与纯 C/C++ 库相当的 性能水平(在内存使用和计算时间方面)。

官网:https://graph-tool.skewed.de/
文档:https://graph-tool.skewed.de/static/doc/index.html
论坛:https://forum.skewed.de/c/graph-tool/5
GitLab:https://git.skewed.de/count0/graph-tool

该包的缺点也很明显:

  • 不支持windows
  • 文字不能换行(有人提到过,但作者摆了)https://git.skewed.de/count0/graph-tool/-/issues/549
  • 不能根据指定长宽比绘图

数据

sample.csv

采样方法 大类 小类
低空遥感解译 地面 裸土地,人工地面
地面影像解译 水生植物 水葫芦,荷叶,苦草,黑藻,水华,水白菜
RTK测量 禾本植物 狗牙根,华克拉莎,斑茅,苔草,芦苇,芦竹,杂茅
RTK测量 竹 风箱树,马甲子
RTK测量 灌木 车筒竹,泰竹,凤尾竹
RTK测量 乔木 旱柳,垂柳,桂花,乌桕,樟树,枫香,银杏,桉树,楝,榆树
低空遥感解译 水稻 已收割,已焚烧,禾苗
低空遥感解译 菜地 铺草,菜苗
地面影像解译 景观树 景观树,景观灌木
低空遥感解译 人造物 房屋,木桥,船,车

代码

import numpy as np
from graph_tool.all import *


# 2字中间加空格
def space_in_name(name):
    if len(name) == 2:
        return f'{name[0]}   {name[1]}'
    return name


# 需要重点突出的类别
def bold_in_name(v):
    if vname[v] in ['RTK测量', '桂花', '车筒竹', '华克拉莎', '水葫芦', '船']:
        vfweight[v] = 1
        vweight[v] = 0.5 * scale
        vfsize[v] = 16 * scale
        vsize[v] = 65 * scale
    else:
        vfweight[v] = 0
        vweight[v] = 1 * scale
        vfsize[v] = 12 * scale
        vsize[v] = 50 * scale


scale = 5   # 总体缩放控制
# 画一个图B->A
g = Graph()
g.set_directed(True)  # 设置为有向图
# 新建顶点属性
vname = g.new_vertex_property("string")  # 顶点名称
vweight = g.new_vertex_property("float")  # 顶点权重
vcolor = g.new_vertex_property("string")  # 顶点边框颜色
vfcolor = g.new_vertex_property("string")  # 顶点填充颜色
vsize = g.new_vertex_property("float")  # 顶点大小
vfsize = g.new_vertex_property("float")  # 顶点文字大小
vfweight = g.new_vertex_property("int")  # 顶点文字粗细 0:正常 1:粗体
# 新建边属性
ecolor = g.new_edge_property("string")  # 边颜色
emarker = g.new_edge_property("string")  # 边标记(箭头)


# 加载数据
data_path = '/home/dl/temp/sample.csv'
data = np.loadtxt(data_path, dtype=np.str_, delimiter=' ', skiprows=1)
list_a = data[:, 0].tolist()
list_b = data[:, 1].tolist()
list_c = data[:, 2].tolist()
# 第一列去重,第三列分割+去重
set_a = list(set(list_a))
list_c = [i.split(',') for i in list_c]
set_c = list(set([j for i in list_c for j in i]))


# 添加顶点
v_a = []
for i in set_a:
    # 添加顶点
    v = g.add_vertex()
    # 设置顶点属性
    vname[v] = space_in_name(i)
    vcolor[v] = "red"
    vfcolor[v] = "lightpink"
    bold_in_name(v)
    vsize[v] = vsize[v] * 1.5
    v_a.append(v)

v_b = []
for i in list_b:
    v = g.add_vertex()
    vname[v] = space_in_name(i)
    vcolor[v] = "orange"
    vfcolor[v] = "lightyellow"
    bold_in_name(v)
    vsize[v] = vsize[v] * 1.2
    v_b.append(v)

v_c = []
for i in set_c:
    v = g.add_vertex()
    vname[v] = space_in_name(i)
    vcolor[v] = "green"
    vfcolor[v] = "lightgreen"
    bold_in_name(v)
    v_c.append(v)

# 添加边 a->b
for i in range(len(list_a)):
    # 添加边
    e = g.add_edge(v_a[set_a.index(list_a[i])], v_b[i])
    # 设置边属性
    ecolor[e] = "darkred"
    emarker[e] = "arrow"

# 添加边 b-c
for i in range(len(list_b)):
    for j in range(len(list_c[i])):
        e = g.add_edge(v_b[i], v_c[set_c.index(list_c[i][j])])
        ecolor[e] = "darkorange"
        emarker[e] = "none"


# 画图 https://graph-tool.skewed.de/static/doc/autosummary/graph_tool.draw.graph_draw.html
graph_draw(g, output="/home/dl/temp/fig.png",
           output_size=(int(1000*scale), int(1000*scale)),   # 画布大小
           pos=sfdp_layout(g, vweight=vweight, p=4),         # 布局算法 https://graph-tool.skewed.de/static/doc/autosummary/graph_tool.draw.sfdp_layout.html
           vertex_text=vname,
           vertex_color=vcolor,
           vertex_fill_color=vfcolor,
           vertex_font_weight=vfweight,
           vertex_font_size=vfsize,
           vertex_pen_width=1*scale,
           vertex_text_position=-2,     # 默认-1:顶点大小随文字缩放, -2:顶点大小不随文字缩放,由vertex_size控制
           vertex_size=vsize,
           edge_color=ecolor,
           edge_pen_width=1.2*scale,
           edge_marker_size=10*scale,
           edge_end_marker=emarker,
           )
           

你可能感兴趣的:(python,网络关系图)