python - Python底图在缩放时改变分辨率
问题描述
我试图在用户缩放时更改地图的分辨率以节省内存和处理时间。我已经尝试了以下代码,但即使每次缩放时地图分辨率都会发生变化,但图形不会更新,我被粗略的分辨率所困扰。关于如何在用户缩放时强制地图更新其分辨率的任何想法?谢谢!
这是我尝试过的代码:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
# create new figure, axes instances
fig = plt.figure(dpi=150)
ax = fig.add_axes([0.1,0.1,0.8,0.8])
# setup mercator map projection
map = Basemap(projection='merc',llcrnrlat=-58,urcrnrlat=80,
llcrnrlon=-180,urcrnrlon=180,resolution='c')
map.drawcoastlines(linewidth=0.50)
map.fillcontinents()
map.drawmapboundary()
# Declare and register callbacks for zoom control
def on_lims_change(axes):
xrange = abs(ax.get_xlim()[1] - ax.get_xlim()[0])
yrange = abs(ax.get_xlim()[1] - ax.get_xlim()[0])
# try to change map resolution based on zoom level
if max(xrange,yrange) < 1E7 and max(xrange,yrange) > 1E6: # 'l' = low
map.resolution = 'l'
elif max(xrange,yrange) < 1E6 and max(xrange,yrange) > 5E5: # 'i' = intermeditate
map.resolution = 'i'
elif max(xrange,yrange) < 5E5 and max(xrange,yrange) > 1E5: # 'h' = high
map.resolution = 'h'
elif max(xrange,yrange) < 1E5: # 'f' = full
map.resolution = 'f'
else: # 'c' = coarse
map.resolution = 'c'
print(map.resolution)
map.drawcoastlines(linewidth=0.50)
map.fillcontinents()
map.drawmapboundary()
ax.callbacks.connect('xlim_changed', on_lims_change)
plt.show()
解决方案
我发现的最好方法是调用类似的东西
zoomcall = ax.callbacks.connect('ylim_changed', onzoom)
ax.patches.clear()
ax.collections.clear()
ax.callbacks.disconnect(zoomcall)
为了(1)建立回调,(2)清除旧地图和(3)清除回调。这是作为易于使用的新类的一部分完成的。
这是代码大纲:
class ZoomPlot():
def __init__(self, pnts):
self.fig = plt.figure(figsize=(15,9))
self.ax = self.fig.add_subplot(111)
self.bnds = self.bnds_strt = [-58, 80, -180, 180]
self.resolution = 'c'
self.plot_map()
def plot_map(self):
self.map = Basemap(projection='merc',llcrnrlat=self.bnds[0],urcrnrlat=self.bnds[1],
llcrnrlon=self.bnds[2],urcrnrlon=self.bnds[3],resolution=self.resolution)
self.map.drawcoastlines()
self.map.drawmapboundary(fill_color='cornflowerblue')
self.map.fillcontinents(color='lightgreen', lake_color='aqua')
self.map.drawcountries()
self.map.drawstates()
self.plot_points()
self.fig.canvas.draw()
self.zoomcall = self.ax.callbacks.connect('ylim_changed', self.onzoom)
def onzoom(self, axes):
#print('zoom triggered')
self.ax.patches.clear()
self.ax.collections.clear()
self.ax.callbacks.disconnect(self.zoomcall)
x1, y1 = self.map(self.ax.get_xlim()[0], self.ax.get_ylim()[0], inverse = True)
x2, y2 = self.map(self.ax.get_xlim()[1], self.ax.get_ylim()[1], inverse = True)
self.bnds = [y1, y2, x1, x2]
# reset zoom to home (workaround for unidentified error when you press the home button)
if any([a/b > 1 for a,b in zip(self.bnds,self.bnds_strt)]):
self.bnds = self.bnds_strt # reset map boundaryies
self.ax.lines.clear() # reset points
self.ab.set_visible(False) # hide picture if visible
# change map resolution based on zoom level
zoom_set = max(abs(self.bnds[0]-self.bnds[1]),abs(self.bnds[2]-self.bnds[3]))
if zoom_set < 30 and zoom_set >= 3:
self.resolution = 'l'
#print(' --- low resolution')
elif zoom_set < 3:
self.resolution = 'i'
#print(' --- intermeditate resolution')
else:
self.resolution = 'c'
#print(' --- coarse resolution')
self.plot_map()
推荐阅读
- javascript - 将 IFrame SRC 绑定到 VueJS 数据
- c# - Unity2D 错误:“对象引用未设置为对象的实例
- ios - iOS App - 为每个新的一天更新字符串数组
- concatenation - 这个关于如何在excel中合并数据的问题
- vagrant - ruby 和 vagrant 会发生什么?
- vue.js - eslint - 在我的 vue 项目中使用数组解构
- postgresql - 用更有效的方法替换数十个连接以计算单独分组的列
- python - 参数化基于 ORM 的 SqlAlchemy 查询
- mongodb-atlas - MongoDB Charts 自定义分箱百分比
- c# - 选项属性未按预期设置默认值