利用python绘制土地利用桑基图
概要
在做关于土地利用的相关论文中,常常利用桑基图可视化土地利用之间的转移。而桑基图的绘制有许多方法,接下来结合python中的plotly来绘制。
土地利用转移矩阵数据
后续将采用的土地利用数据
绘制桑基图
1.先绘制两时间节点的,即2000-2010年的
import plotly.graph_objects as go
# 定义转移矩阵
transfer_matrix_2000_to_2010 = [
[383.69, 3.51, 0.02, 7.19, 4.27, 0.24],
[8.66, 166.07, 1.44, 63.02, 17.73, 39.24],
[0, 0.88, 3.73, 0.09, 0.01, 0.23],
[12.76, 29.42, 1.1, 79.35, 11.97, 25.42],
[0.27, 3.73, 0.03, 1.64, 1.72, 0.94],
[2.14, 4.39, 0.05, 11.69, 1.15, 2.75]
]
# 类别名称
categories = ["林地", "建设用地", "水域", "耕地", "未利用地", "草地"]
# 创建节点(起始节点和目标节点)
labels = []
labels.extend([f"2000_{category}" for category in categories])
labels.extend([f"2010_{category}" for category in categories])
# 创建 source 和 target
source = []
target = []
value = []
# 2000 到 2010 的转移数据
for i in range(len(categories)):
for j in range(len(categories)):
if transfer_matrix_2000_to_2010[i][j] > 0:
source.append(i) # 从 2000 年的类别
target.append(len(categories) + j) # 到 2010 年的类别
value.append(transfer_matrix_2000_to_2010[i][j])
# 定义颜色
colors = [
"#228B22", # 林地 (深绿色)
"#D2691E", # 建设用地 (深橙色)
"#1E90FF", # 水域 (亮蓝色)
"#FFD700", # 耕地 (金色)
"#A9A9A9", # 未利用地 (暗灰色)
"#7CFC00" # 草地 (草绿色)
]
# 创建桑基图
fig = go.Figure(go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.5),
label=labels,
color=colors * 2 # 为每个时间点的节点分配相同的颜色
),
link=dict(
source=source,
target=target,
value=value,
color=[colors[i] for i in source] # 使用相应类别的颜色
)
))
# 更新图形布局
fig.update_layout(title_text="土地利用转移桑基图", font_size=10)
fig.show()
绘制桑基图如下:
2.先绘制多时间节点的,即2000-2010年和2010-2020年的
import plotly.graph_objects as go
# 转移矩阵
transfer_matrix_2000_to_2010 = [
[383.69, 3.51, 0.02, 7.19, 4.27, 0.24],
[8.66, 166.07, 1.44, 63.02, 17.73, 39.24],
[0, 0.88, 3.73, 0.09, 0.01, 0.23],
[12.76, 29.42, 1.1, 79.35, 11.97, 25.42],
[0.27, 3.73, 0.03, 1.64, 1.72, 0.94],
[2.14, 4.39, 0.05, 11.69, 1.15, 2.75]
]
transfer_matrix_2010_to_2020 = [
[383.69, 8.66, 0, 12.76, 0.27, 2.14],
[3.51, 166.07, 0.88, 29.42, 3.73, 4.39],
[0.02, 1.44, 3.73, 1.1, 0.03, 0.05],
[7.19, 63.02, 0.09, 79.35, 1.64, 11.69],
[4.27, 17.73, 0.01, 11.97, 1.72, 1.15],
[0.24, 39.24, 0.23, 25.42, 0.94, 2.75]
]
# 类别名称
categories = ["林地", "建设用地", "水域", "耕地", "未利用地", "草地"]
# 创建节点标签
labels = []
for year in ["2000", "2010", "2020"]:
labels.extend([f"{year} {category}" for category in categories])
# 创建 source 和 target
source = []
target = []
value = []
# 2000 到 2010 年的转移数据
for i in range(len(categories)):
for j in range(len(categories)):
if transfer_matrix_2000_to_2010[i][j] > 0:
source.append(i) # 从 2000 年的类别
target.append(len(categories) + j) # 到 2010 年的类别
value.append(transfer_matrix_2000_to_2010[i][j])
# 2010 到 2020 年的转移数据
for i in range(len(categories)):
for j in range(len(categories)):
if transfer_matrix_2010_to_2020[i][j] > 0:
source.append(len(categories) + i) # 从 2010 年的类别
target.append(2 * len(categories) + j) # 到 2020 年的类别
value.append(transfer_matrix_2010_to_2020[i][j])
# 定义颜色
colors = [
"#228B22", # 林地 (深绿色)
"#D2691E", # 建设用地 (深橙色)
"#1E90FF", # 水域 (亮蓝色)
"#FFD700", # 耕地 (金色)
"#A9A9A9", # 未利用地 (暗灰色)
"#7CFC00" # 草地 (草绿色)
]
# 创建桑基图
fig = go.Figure(go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.5),
label=labels,
color=colors * 3 # 每个时间节点的类别都有同样的颜色,重复3次
),
link=dict(
source=source,
target=target,
value=value,
color=[colors[i % len(colors)] for i in source] # 使用取模操作来避免超出索引
)
))
# 更新图形布局
fig.update_layout(title_text="土地利用转移桑基图", font_size=10)
fig.show()
绘制桑基图如下:
小结
最后可以根据自己的数据修改上面的代码,包括颜色,可以去查找十六进制颜色去替换
作者:默默乎也