社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python绘制中国版dem地图

happy科研 • 3 年前 • 818 次点击  

背景

前几天看到一个人分享的中国的dem数据可视化实在是太好看了。这里我想用python复刻一下。

过程

1. 数据:

数据已经上传到我的网盘上了,关注公众号【world of statistics】然后回复【气象数据】即可获得。

2. 代码

# 导入包
import rasterio
import numpy as np
import matplotlib.pyplot as plt
from getchinamap.getchinamap import DownloadChmap
import rasterio.mask
import cartopy.crs as ccrs
import matplotlib as mpl
import datetime
dl_engine = DownloadChmap()

# 获得数据
dem_raw_data = rasterio.open("数据集/ChinaDEM1km_WGS84.tif")

这个数据的详情如下:
# 这里以西藏自治区为例:

# china_boundary_gdf = dl_engine.download_country(target='边界')
province_name = '西藏自治区'
china_boundary_gdf = dl_engine.download_province(province_name=province_name,target='边界')
china_boundary_gdf_sub = dl_engine.download_province(province_name=province_name,target='市')
# china_boundary_gdf = dl_engine.download_country(target='边界')
# china_boundary_gdf_sub = dl_engine.download_country(target='省')
china_boundary_gdf_sub

# 对dem做裁切
out_image, out_transform = rasterio.mask.mask(dem_raw_data, china_boundary_gdf['geometry'], crop=True)
out_meta = dem_raw_data.meta
out_meta.update({"driver""GTiff",
                 "height": out_image.shape[1],
                 "width": out_image.shape[2],
                 "transform": out_transform})
                 
                 
clean_data = out_image.copy().astype('float')
clean_data = clean_data[0, :, :]
clean_data[clean_data == out_meta['nodata']] = np.nan

3. 使用ccrs.PlateCarree()投影

接下来是使用ccrs.PlateCarree()投影,使用这个投影的原因是可视化快。代码如下:


mat_extent = [getattr(out_transform, 'c'),
              getattr(out_transform, 'c') + clean_data.shape[1] * getattr(out_transform, 'a'),
              getattr(out_transform, 'f') + clean_data.shape[0] * getattr(out_transform, 'e'),
              getattr(out_transform, 'f')]

colors = ["#33A02C""#B2DF8A""#FDBF6F""#1F78B4""#999999""#E31A1C""#E6E6E6" "#A6CEE3"]

myccrs = ccrs.PlateCarree()

fig, ax = plt.subplots(figsize=(105), dpi=150, subplot_kw={'projection': myccrs})

ax.gridlines(draw_labels=True,
             linewidth=2, color='gray', alpha=0.5, linestyle='--')

ax_im_bar = ax.imshow(clean_data, origin='upper', extent=mat_extent, transform=myccrs,
                      cmap=mpl.colors.LinearSegmentedColormap.from_list("mypalette", colors, N=1000))

china_boundary_gdf_sub.boundary.plot(ax=ax, color='black', linewidth=1)

fig.colorbar(ax_im_bar, orientation='vertical')
# plt.tight_layout()
#
# ax.set_title("china dem")
# ax.set_ylabel("y label")
# ax.set_xlabel("x label")

4. 使用Orthographic投影

但是上面的图不太好看,这里使用Orthographic投影再画一次。但是这个渲染的速度非常慢,需要等待几分钟⌛️~

longitude = np.array(
    [getattr(out_transform, 'c') + i * getattr(out_transform, 'a'for i in range(clean_data.shape[1])])
latitude = np.array(
    [getattr(out_transform, 'f') + i * getattr(out_transform, 'e'for i in range(clean_data.shape[0])])

colors = ["#33A02C""#B2DF8A""#FDBF6F""#1F78B4""#999999""#E31A1C""#E6E6E6""#A6CEE3"]
center_china_point = china_boundary_gdf.centroid[0]

# 新的兰伯特投影
new_crs = ccrs.Orthographic(central_longitude=center_china_point.x,
                                central_latitude=center_china_point.y)
myccrs = ccrs.PlateCarree()

fig, ax = plt.subplots(figsize=(1010), dpi=100, subplot_kw={'projection': new_crs})

ax.gridlines(draw_labels=True,
             linewidth=2, color='gray', alpha=0.5, linestyle='--')
ax_im_bar = ax.contourf(longitude, latitude, clean_data,  # [::-1,:]
                            np.arange(0, np.nanmax(clean_data), 100.0),
                            transform=ccrs.PlateCarree(),
                            cmap=mpl.colors.LinearSegmentedColormap.from_list("mypalette", colors, N=1000),
                            extend='both', origin='upper')
china_boundary_gdf_sub.to_crs(new_crs.proj4_init).boundary.plot(ax=ax, edgecolor='black', linewidth=1)
fig.colorbar(ax_im_bar, orientation='vertical')
# fig.savefig('test1226.png')
fig.savefig(f"test1226_china_{datetime.datetime.now().strftime('%Y-%m-%d %X')}.png")

5. 更多

上面只是选择的 西藏自治区 。实际上可以选别的地区,都可以进行裁剪。但是有的时候渲染非常慢~~

下面是我绘画的中国地图数据。只需要把我上面那个代码修改一下即可!!!

阅读更多

从nc文件中提取风速数据并且进行时间序列分析

2021-12-26

基于FastAPI异步化 为transformers模型 打造高性能接口

2021-12-30

[python新包介绍]交互式地图可视化[1.8w字介绍 阅读需要46分钟]

2021-12-14

[原创]python交互式展示坐标系的映射关系

2021-12-19

[自制]python批量压缩图像

2021-12-20






最后

祝我读者都可以顺利毕业,工作顺利~🚀🚀🚀

🎈🎈🎈🎈元旦快乐🎊🎊

打赏我


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/125298
 
818 次点击