基于Python 利用桑基图(Sankeydiagram)表示转移矩阵(土地利用)

桑基图桑,基能量分流图,也叫桑基能量平衡图。它是一种特定类型的流程图,图中延伸的分支的宽度对应数据流量的大小,通常应用于能源、材料成分、金融等数据的可视化分析。因1898年Matthew Henry Phineas Riall Sankey绘制的“蒸汽机的能源效率图”而闻名,此后便以其名字命名为“桑基图”。

查看源图像

看到这么炫酷的图,是不是心动了呢 

对于土地利用文献中大多使用转移矩阵的方式。本博客实现2000年,2005年,2010年,2015年,2019年土地利用之间的转移情况使用桑基图可视化。

首选,这里土地利用与编号对应如下:

123456789
ForestGrasslandGrasslandCultivated LandArtifical SurfaceWater BodyWetlandSnow and IceBare Land

 

使用栅格计算器工具基于2000.tif,2005.tif,2010.tif,2015.tif,2019.tif。四期数据,计算五期数据的转移情况,

公式如下:

10000*2000.tif+1000*2005.tif+100*2010.tif+10*2015.tif+2019.tif.。

得到栅格数据即为转移情况,将栅格数据的属性表导出到本地,如下,其中,11113表示2000,2005,2010,2015是1,2019是3。


笔者在后面添加十个表头,如下。将Value值拆分,分别赋值给a1-a5,name1-name5用于存储五期数据土地利用名字,如Forest(2000),Forest(2005)等

读者可以将数据做成如上格式,首选进行Value值的拆分和赋值

import pandas as pd

path=r'D:\study\tmp'
import os
os.chdir(path)
name='2000_2005_2010_2015_2019.csv'
#name='sankey - 副本.csv'
df=pd.read_csv(name)
df['a1']=df['Value']//10000
df['a2']=(df['Value']-df['a1']*10000)//1000
df['a3']=(df['Value']-df['a1']*10000-df['a2']*1000)//100
df['a4']=(df['Value']-df['a1']*10000-df['a2']*1000-df['a3']*100)//10
df['a5']=df['Value']-df['a1']*10000-df['a2']*1000-df['a3']*100-df['a4']*10

name2000=['Forest(2000)','Grassland(2000)','Shrubland(2000)','Cultivated Land(2000)','Artifical Surface(20000)',
      'Water Body(2000)','Wetland(2000)','Snow and Ice(2000)','Bare Land(2000)']

name2005=['Forest(2005)','Grassland(2005)','Shrubland(2005)','Cultivated Land(2005)','Artifical Surface(2005)',
      'Water Body(2005)','Wetland(2005)','Snow and Ice(2005)','Bare Land(2005)']

name2010=['Forest(2010)','Grassland(2010)','Shrubland(2010)','Cultivated Land(2010)','Artifical Surface(2010)',
      'Water Body(2010)','Wetland(2010)','Snow and Ice(2010)','Bare Land(2010)']

name2015=['Forest(2015)','Grassland(2015)','Shrubland(2015)','Cultivated Land(2015)','Artifical Surface(2015)',
      'Water Body(2015)','Wetland(2015)','Snow and Ice(2015)','Bare Land(2015)']

name2019=['Forest(2019)','Grassland(2019)','Shrubland(2019)','Cultivated Land(2019)','Artifical Surface(2019)',
      'Water Body(2019)','Wetland(2019)','Snow and Ice(2019)','Bare Land(2019)']
import numpy as np
b1=np.array(df['a1'])
b2=np.array(df['a2'])
b3=np.array(df['a3'])
b4=np.array(df['a4'])
b5=np.array(df['a5'])

def f(b,name):
    re=[]
    for i in range(len(b)):
        #print(b[i])
        re.append(name[b[i]])
        
    return re
        
        

n1=f(b1,name2000)
n2=f(b2,name2005)
n3=f(b3,name2010)
n4=f(b4,name2015)
n5=f(b5,name2019)
df['name1']=n1
df['name2']=n2
df['name3']=n3
df['name4']=n4
df['name5']=n5
df.to_csv('re.csv')

处理后的结果如下:

然后我们将Value,a1,a2,a3,a4,a5,列删除,当然也可以在用Pandas读取时,只读取这几行。笔者采取直接删除的方式,

 

下面我们将数据进行预处理,处理成Sankey绘图需要的格式,生成nodes 和linkes

from pyecharts import options as opts
from pyecharts.charts import Sankey
import pandas as pd

import os
path=r'D:\study\tmp'
os.chdir(path)
name='sankey.csv'
name='re1.csv'
#name='sankey - 副本.csv'
df=pd.read_csv(name)
nodes=[]
for i in range(5):
    values=df.iloc[:,i].unique()
    for value in values:
        #print(value)
        dic={}
        dic['name']=value
        nodes.append(dic)
        
print(nodes)

f1=df.groupby(['name1','name2'])['Count'].sum().reset_index()
f2=df.groupby(['name2','name3'])['Count'].sum().reset_index()
f3=df.groupby(['name3','name4'])['Count'].sum().reset_index()
f4=df.groupby(['name4','name5'])['Count'].sum().reset_index()

f1.columns=['source','target','value']
f2.columns=['source','target','value']
f3.columns=['source','target','value']
f4.columns=['source','target','value']
result=pd.concat([f1,f2,f3,f4])




linkes=[]
for i in result.values:
    dic={}
    dic['source']=i[0]
    dic['target']=i[1]
    dic['value']=i[2]
    linkes.append(dic)
print(linkes)

nodes的结果如下:

linkes的结果如下:形式为source-target-value

最后绘制桑吉图

from pyecharts.charts import Sankey
from pyecharts import options as opts
 
 
pic = (
    Sankey()
    .add('',
         nodes,
         linkes,
         linestyle_opt=opts.LineStyleOpts(opacity = 0.3, curve = 0.5, color = 'source'),
         label_opts=opts.LabelOpts(position = 'top'),
         node_gap = 30,
    )
    .set_global_opts(title_opts=opts.TitleOpts(title = ''))
)

 
 
pic.render('2000_2005_2010_2015_2019.html')

打开html文件,结果如下:

土地利用转移矩阵是一个描述地表覆盖变化的矩阵,它可以用来预测未来的土地利用变化趋势。在Python中,可以使用numpy库来处理矩阵运算。 首先,我们需要初始化一个土地利用转移矩阵。假设我们有4种土地利用类型(A、B、C、D),那么一个简单的转移矩阵可以这样定义: ``` import numpy as np # 定义土地利用类型 land_use_types = ['A', 'B', 'C', 'D'] # 定义转移矩阵,每一行表示从一个土地利用类型转移到其他土地利用类型的概率 trans_matrix = np.array([ [0.4, 0.3, 0.2, 0.1], [0.2, 0.4, 0.3, 0.1], [0.1, 0.2, 0.4, 0.3], [0.1, 0.1, 0.2, 0.6] ]) ``` 上面的矩阵定义了四个土地利用类型之间的转移概率。例如,第一行表示从类型A转移到其他类型的概率分别为0.4、0.3、0.2和0.1。 接下来,我们可以使用矩阵乘法来计算未来的土地利用变化。假设当前的土地利用类型分布为[0.3, 0.2, 0.4, 0.1],那么下一时刻的土地利用类型分布可以这样计算: ``` # 定义当前的土地利用类型分布 current_land_use = np.array([0.3, 0.2, 0.4, 0.1]) # 计算下一时刻的土地利用类型分布 next_land_use = np.dot(current_land_use, trans_matrix) print(next_land_use) ``` 输出结果为: ``` [0.24 0.26 0.29 0.21] ``` 这表示在下一时刻,土地利用类型A、B、C、D的分布分别为0.24、0.26、0.29和0.21。我们可以继续使用这种方法计算未来的土地利用变化。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是菜鸡,我不敢睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值