使用 python 的 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

该包的缺点也很明显:

数据

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,
           )
           
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值