当前位置:首页>python>3-[Python]"时间-区间-数值"3D表面绘图

3-[Python]"时间-区间-数值"3D表面绘图

  • 2026-08-26 02:15:01
3-[Python]"时间-区间-数值"3D表面绘图

基于矢量面数据属性表绘制三维表面分布图

1. 试验简介

基于土地利用类型面数据属性表,选取面积字段(area),按某一数值将面积范围划分为等间距的面积区间,根据区间统计土地利用类型斑块数量(count)和总和面积(total square),进而利用Python的第三方库matplotlib绘制“时间-面积区间-斑块数量/总和面积”三维表面。

2. 数据信息

(1)产品来源:MCD12Q1土地利用/覆被数据集

数据批量下载见:空间数据炼金术 | 1-土地覆被栅格数据批量下载

(2)数据名称:2001-2024年土地利用面数据属性表(.xls文件)

数据获取批量操作见:

① 土地利用栅格数据转换为矢量面数据:地学统计分析 | 3-土地覆被点数据批量提取,看这一篇就够了

② 面数据批量添加面积字段、计算面积与导出属性表:地学统计分析 | 5-[Arcpy]面数据批量添加面积字段、计算面积并导出属性表

3. 绘图过程

(1)结果图

(2)[Python]代码

① 第三方库导入

1
2
3
4
5
6

import osimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport matplotlib.colors as mcolorsfrom matplotlib.ticker import ScalarFormatter

② 土地利用面数据属性表所在文件夹路径

1

folder1_path = r"土地利用面数据属性表所在文件夹绝对路径"

③ 提取年份、定义面积区间、获取区间内斑块数量与总和面积

定义函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

def process_folder(folder_path):    files = []    years = set()    for root, dirs, fs in os.walk(folder_path):        for f in fs:            if f.endswith('.xls'):                file_path = os.path.join(root, f)                year = int(f[:4])                years.add(year)                df = pd.read_excel(file_path)                if 'area' in df.columns:                    files.append([year, df['area'].values])    min_area = min([np.min(data[1]) for data in files])    max_area = max([np.max(data[1]) for data in files])    bins = np.arange(min_area, max_area+100, 1000)#区间间隔    counts_df = pd.DataFrame(index=bins[:-1], columns=sorted(years))    sums_df = pd.DataFrame(index=bins[:-1], columns=sorted(years))    for year in sorted(years):        year_areas = [data[1] for data in files if data[0] == year]        flat_areas = np.concatenate(year_areas)        counts, _ = np.histogram(flat_areas, bins=bins)        counts_df[year] = counts        sums = [np.sum(area[np.digitize(area, bins) == i]) for i in range(1, len(bins)) for area in year_areas]        sums_df[year] = sums    return counts_df, sums_df

执行计算:

1
2
3
4
5
6

count_dfs = []sum_dfs = []for folder_path in [folder1_path]:    counts_df, sums_df = process_folder(folder_path)    count_dfs.append(counts_df)    sum_dfs.append(sums_df)

打印结果:

区间斑块数量:

1

count_dfs[0].iloc[:,:]

区间总和面积:

1

sum_dfs[0].iloc[:,:]

④ “时间-面积区间-斑块数量/总和面积”三维表面绘图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 设置图形布局为 1 行 2 列fig, axes = plt.subplots(1, 2, figsize=(15, 10), subplot_kw={'projection': '3d'})for i, (quantity_df, sum_df) in enumerate(zip(count_dfs, sum_dfs)):    years = quantity_df.columns    ranges = quantity_df.index    X, Y = np.meshgrid(ranges, years)    Z_quantity = quantity_df.values    ax = axes[0]    surf_counts=ax.plot_surface(X, Y, Z_quantity.T, cmap='RdYlBu',label='counts',                                shade=True,                                rcount=Z_quantity.T.shape[0],                                 ccount=Z_quantity.T.shape[1])#Z_quantity.T.shape[1]    ax.set_xlabel('Range')    ax.set_ylabel('Year')    ax.set_zlabel('total counts')    ax.set_title(f'counts along time Distribution')    # 添加 colorbar 到数量图    fig.colorbar(surf_counts, ax=ax, shrink=0.2, aspect=15,pad=0.08)    Z_sum = sum_df.values    ax = axes[1]    surf_sum=ax.plot_surface(X, Y, Z_sum.T, cmap='RdYlBu',label='total square',                            shade=True,                            rcount=Z_sum.T.shape[0],                             ccount=Z_sum.T.shape[1])#Z_sum.T.shape[1]    ax.set_xlabel('Range')    ax.set_ylabel('Year')    ax.set_zlabel('total square')    ax.set_title(f'total square along time Distribution')    # 添加 colorbar 到求和图    fig.colorbar(surf_sum,ax=ax,shrink=0.2, aspect=15,pad=0.08)plt.tight_layout()plt.savefig('数量面积三维图.jpg',dpi=600,bbox_inches='tight')plt.show()

点个“看一看”吧

最新文章

随机文章