使用Python的basemap模块绘制地图的局部放大图(主图及放大的子图)

1、地图的局部放大图的效果图

​​​​​在这里插入图片描述

2、地图的局部放大图的代码

# -*- coding: utf-8 -*-
"""
Created on Sat Feb  6 20:43:07 2021

@author: sunpuyu
"""

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
import numpy as np

# 主图和子图的经纬度区间
mainMapLlcrnrlat=35.3
mainMapUrcrnrlat = 40.3
mainMapLlcrnrlon = -125
mainMapUrcrnrlon = -120

subMapLlcrnrlat=37.7
subMapUrcrnrlat = 37.9
subMapLlcrnrlon = -122.55
subMapUrcrnrlon = -122.35

#SAR图像的四个点的坐标1:右上,2:左上,3:左下,4:右下
sarPointLon1=-122.390250556259
sarPointLon2=-122.542439019235
sarPointLon3=-122.5171013227481
sarPointLon4=-122.3601877539973
sarPointLat1=37.85626168213586
sarPointLat2=37.83125355749024
sarPointLat3=37.7236791270483
sarPointLat4=37.74816614839607

myFontSize=30 #字体大小
myBackgroundPicture='World_Topo_Map'#底图类型
myLat0 = (subMapLlcrnrlat+subMapUrcrnrlat)/2.0#投影中心
myLon0 = (subMapLlcrnrlon+subMapUrcrnrlon)/2.0
myPixels=50000#底图的像素

def div_mark(minVal,maxVal,n):
    marks=np.linspace(minVal, maxVal, n)
    return np.around(marks[1:-1:2],2)

if __name__ == "__main__":
    fig=plt.figure(figsize=(16,8))
    ax = fig.add_subplot(111)#添加子图
    
    map = Basemap(projection='merc',llcrnrlat = mainMapLlcrnrlat, urcrnrlat = mainMapUrcrnrlat, 
                  llcrnrlon = mainMapLlcrnrlon, urcrnrlon = mainMapUrcrnrlon,epsg = 4269,
                  lat_0 = myLat0, lon_0 = myLon0)
    
    #主图的经纬度刻度
    map.drawmeridians(meridians=div_mark(mainMapLlcrnrlon, mainMapUrcrnrlon, 5), labels=[0, 0, 1, 1], color='none',fontsize=myFontSize)
    map.drawparallels(circles=div_mark(mainMapLlcrnrlat, mainMapUrcrnrlat, 5), labels=[1, 0, 0, 0], color='none',fontsize=myFontSize,rotation = 90)
    map.drawparallels(circles=div_mark(mainMapLlcrnrlat, mainMapUrcrnrlat, 5), labels=[0, 1, 0, 0], color='none',fontsize=myFontSize,rotation = 270)
    
    map.arcgisimage(service=myBackgroundPicture, xpixels = myPixels, verbose= True)#加在高清底图(背景)
    
    axins = zoomed_inset_axes(ax, 30, loc='center left', bbox_to_anchor=(-260, 290))
    axins.set_xlim(subMapLlcrnrlon, subMapUrcrnrlon)
    axins.set_ylim(subMapLlcrnrlat, subMapUrcrnrlat)
    submap = Basemap(projection='merc',llcrnrlat = subMapLlcrnrlat, urcrnrlat = subMapUrcrnrlat, 
                  llcrnrlon = subMapLlcrnrlon, urcrnrlon = subMapUrcrnrlon,ax=axins,epsg = 4269,
                  lat_0 = myLat0, lon_0 = myLon0)
    #画线
    submap.plot([sarPointLon1,sarPointLon2],[sarPointLat1,sarPointLat2],linewidth=2,color='r',latlon='True')
    submap.plot([sarPointLon2,sarPointLon3],[sarPointLat2,sarPointLat3],linewidth=2,color='r',latlon='True')
    submap.plot([sarPointLon3,sarPointLon4],[sarPointLat3,sarPointLat4],linewidth=2,color='r',latlon='True')
    submap.plot([sarPointLon4,sarPointLon1],[sarPointLat4,sarPointLat1],linewidth=2,color='r',latlon='True')
    #子图的经纬度刻度
    submap.drawmeridians(meridians=div_mark(subMapLlcrnrlon, subMapUrcrnrlon, 5), labels=[0, 0, 1, 1], color='none',fontsize=myFontSize)
    submap.drawparallels(circles=div_mark(subMapLlcrnrlat, subMapUrcrnrlat, 5), labels=[1, 0, 0, 0], color='none',fontsize=myFontSize,rotation = 90)
    submap.drawparallels(circles=div_mark(subMapLlcrnrlat, subMapUrcrnrlat, 5), labels=[0, 1, 0, 0], color='none',fontsize=myFontSize,rotation = 270)
    
    submap.arcgisimage(service=myBackgroundPicture, xpixels = myPixels, verbose= True)#加在高清底图(背景)
    mark_inset(ax, axins, loc1=1, loc2=4, fc="none", ec="0.1",linestyle='--')#标记放大区域
    #submap.drawmapscale(subMapLlcrnrlon,subMapLlcrnrlat,myLon0,myLat0, 10, barstyle='fancy')#比例尺
    plt.show()
    #fig.savefig('sar1',dpi=600,format='eps')

3、具体的细节及参考

1、可以绘制地图的库有很多:basemap、folium、pyecharts、plotly等等,可以参考Python 如何画出漂亮的地图?;我这里用的basemap库,安装basemap请自行百度。
注意*:basemap是基于matplotlib库编写的,很多函数中的参数设置都相同(比如字体、颜色、线条等等)*

2、局部放大效果的函数有:add_subplot()、zoomed_inset_axes()、mark_inset()
具体使用方法参考链接:Basemap系列教程:绘制子图及小地图

3、高清背景地图的选择。basemap自带的地图分辨率有限,可能你需要画某个比较小的地方时地图中只有马赛克了,需要借助其他的函数如arcgisimage()。具体使用方式参考basemap高清背景地图;背景地图的类型参考基于python的arcgis底图添加
***注意:*arcgisimage函数是每次运行从数据库中下载你需要的背景地图,其中的参数xpixels表示x轴方向的分辨率(y轴使用默认的比例就行),数字越大分辨率越高,但是当分辨率很高时,可能下载失败。

4、地图投影方式及坐标系统选择。投影方式关键字为“projection”,可参考官网博客;坐标系统关键字为“epsg ”,参考博客选择自己需要的系统。

5、在地图上画线使用plot函数

6、调整主图和子图的相对位置使用“loc”和“bbox_to_anchor”两个参数。
在这里插入图片描述
bbox_to_anchor参数的第一个值为x轴方向偏移的量,第二个值为y轴方向偏移的量。偏移量的刻度与坐标轴的刻度一致。偏移量1对应的角度应该是1秒。需要与loc参数搭配使用。

7、也可以参考matplotlib绘图的博客

8、其他的一些我没用到的功能可以先参考【不迷途导航程序员】公众号的文章我用Python之basemap画图27问

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值