Python basemap change resolution upon zoom
I'm trying to change the resolution of a map when the user zooms in order to save on memory and processing time. I've tried the following code, but even though the map resolution gets changed each time you zoom, the figure does not update and I am stuck with the coarse resolution. Any ideas on how to force the map to update its resolution when the user zooms? Thanks!
Here's the code I've tried:
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()
python matplotlib zoom resolution matplotlib-basemap
add a comment |
I'm trying to change the resolution of a map when the user zooms in order to save on memory and processing time. I've tried the following code, but even though the map resolution gets changed each time you zoom, the figure does not update and I am stuck with the coarse resolution. Any ideas on how to force the map to update its resolution when the user zooms? Thanks!
Here's the code I've tried:
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()
python matplotlib zoom resolution matplotlib-basemap
Try adding afig.canvas.draw()
at the end of youron_lims_change()
function. Also, I think you don't need to redraw the boundaries every time.
– Thomas Kühn
Dec 12 '18 at 7:47
add a comment |
I'm trying to change the resolution of a map when the user zooms in order to save on memory and processing time. I've tried the following code, but even though the map resolution gets changed each time you zoom, the figure does not update and I am stuck with the coarse resolution. Any ideas on how to force the map to update its resolution when the user zooms? Thanks!
Here's the code I've tried:
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()
python matplotlib zoom resolution matplotlib-basemap
I'm trying to change the resolution of a map when the user zooms in order to save on memory and processing time. I've tried the following code, but even though the map resolution gets changed each time you zoom, the figure does not update and I am stuck with the coarse resolution. Any ideas on how to force the map to update its resolution when the user zooms? Thanks!
Here's the code I've tried:
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()
python matplotlib zoom resolution matplotlib-basemap
python matplotlib zoom resolution matplotlib-basemap
edited Nov 28 '18 at 23:50
Oak Nelson
asked Nov 26 '18 at 3:56
Oak NelsonOak Nelson
165
165
Try adding afig.canvas.draw()
at the end of youron_lims_change()
function. Also, I think you don't need to redraw the boundaries every time.
– Thomas Kühn
Dec 12 '18 at 7:47
add a comment |
Try adding afig.canvas.draw()
at the end of youron_lims_change()
function. Also, I think you don't need to redraw the boundaries every time.
– Thomas Kühn
Dec 12 '18 at 7:47
Try adding a
fig.canvas.draw()
at the end of your on_lims_change()
function. Also, I think you don't need to redraw the boundaries every time.– Thomas Kühn
Dec 12 '18 at 7:47
Try adding a
fig.canvas.draw()
at the end of your on_lims_change()
function. Also, I think you don't need to redraw the boundaries every time.– Thomas Kühn
Dec 12 '18 at 7:47
add a comment |
1 Answer
1
active
oldest
votes
Best way I found was to call something like
zoomcall = ax.callbacks.connect('ylim_changed', onzoom)
ax.patches.clear()
ax.collections.clear()
ax.callbacks.disconnect(zoomcall)
in order to (1) establish callback, (2) clear the old map and (3) clear the callback. This is done as part of a new class for ease of use.
Here is the code outline:
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()
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53474600%2fpython-basemap-change-resolution-upon-zoom%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Best way I found was to call something like
zoomcall = ax.callbacks.connect('ylim_changed', onzoom)
ax.patches.clear()
ax.collections.clear()
ax.callbacks.disconnect(zoomcall)
in order to (1) establish callback, (2) clear the old map and (3) clear the callback. This is done as part of a new class for ease of use.
Here is the code outline:
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()
add a comment |
Best way I found was to call something like
zoomcall = ax.callbacks.connect('ylim_changed', onzoom)
ax.patches.clear()
ax.collections.clear()
ax.callbacks.disconnect(zoomcall)
in order to (1) establish callback, (2) clear the old map and (3) clear the callback. This is done as part of a new class for ease of use.
Here is the code outline:
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()
add a comment |
Best way I found was to call something like
zoomcall = ax.callbacks.connect('ylim_changed', onzoom)
ax.patches.clear()
ax.collections.clear()
ax.callbacks.disconnect(zoomcall)
in order to (1) establish callback, (2) clear the old map and (3) clear the callback. This is done as part of a new class for ease of use.
Here is the code outline:
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()
Best way I found was to call something like
zoomcall = ax.callbacks.connect('ylim_changed', onzoom)
ax.patches.clear()
ax.collections.clear()
ax.callbacks.disconnect(zoomcall)
in order to (1) establish callback, (2) clear the old map and (3) clear the callback. This is done as part of a new class for ease of use.
Here is the code outline:
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()
answered Mar 15 at 13:20
Oak NelsonOak Nelson
165
165
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53474600%2fpython-basemap-change-resolution-upon-zoom%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Try adding a
fig.canvas.draw()
at the end of youron_lims_change()
function. Also, I think you don't need to redraw the boundaries every time.– Thomas Kühn
Dec 12 '18 at 7:47