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问。