basemap covering a small area

Hi matplotlib users,

I am interested in making basemap plots covering only a small area. When I do
this the meridians and parallels (and labelling of these) look strange. I
have pasted in a simple example below showing the problem (at least on my
computer):

import pylab
from matplotlib.toolkits import basemap

bmap = basemap.Basemap(120.33, 35.95, 120.55, 36.12)
merid = [120.3, 120.35, 120.4, 120.45, 120.5, 120.55, 120.6]
paral = [35.94, 35.96, 35.98, 36.0, 36.02, 36.04, 36.06, 36.08, 36.1, 36.12,
36.14]
bmap.drawparallels(paral, labels=[1,0,0,0])
bmap.drawmeridians(merid, labels=[0,0,0,1])
pylab.savefig('test.png')

Regards,
Jesper

Jesper Larsen wrote:

Hi matplotlib users,

I am interested in making basemap plots covering only a small area. When I do this the meridians and parallels (and labelling of these) look strange. I have pasted in a simple example below showing the problem (at least on my computer):

import pylab
from matplotlib.toolkits import basemap

bmap = basemap.Basemap(120.33, 35.95, 120.55, 36.12)
merid = [120.3, 120.35, 120.4, 120.45, 120.5, 120.55, 120.6]
paral = [35.94, 35.96, 35.98, 36.0, 36.02, 36.04, 36.06, 36.08, 36.1, 36.12, 36.14]
bmap.drawparallels(paral, labels=[1,0,0,0])
bmap.drawmeridians(merid, labels=[0,0,0,1])
pylab.savefig('test.png')

Regards,
Jesper
  

Jesper: Hmm, I guess I never thought anyone would make a map that small. I tweaked some of the parameters to make it work better (svn revision 3470). Here's the diff in case you just want to apply the patch manually:

···

===================================================================
--- basemap.py (revision 3469)
+++ basemap.py (working copy)
@@ -1665,9 +1665,9 @@
             xoffset = (self.urcrnrx-self.llcrnrx)/100.
          if self.projection in ['merc','cyl','mill','moll','robin','sinu']:
- lons = NX.arange(self.llcrnrlon,self.urcrnrlon+0.1,0.1).astype(NX.Float32)
+ lons = NX.arange(self.llcrnrlon,self.urcrnrlon+0.01,0.01)
         else:
- lons = NX.arange(0,360.1,0.1).astype(NX.Float32)
+ lons = NX.arange(0,360.01,0.01)
         # make sure latmax degree parallel is drawn if projection not merc or cyl or miller
         try:
             circlesl = circles.tolist()
@@ -1729,7 +1729,7 @@
         # search along edges of map to see if parallels intersect.
         # if so, find x,y location of intersection and draw a label there.
         if self.projection == 'cyl':
- dx = 0.01; dy = 0.01
+ dx = 0.001; dy = 0.001
         else:
             dx = 1000; dy = 1000
         if self.projection in ['moll','robin','sinu']:
@@ -1883,11 +1883,11 @@
             xoffset = (self.urcrnrx-self.llcrnrx)/100.
          if self.projection not in ['merc','cyl','mill','moll','robin','sinu']:
- lats = NX.arange(-latmax,latmax+0.1,0.1).astype(NX.Float32)
+ lats = NX.arange(-latmax,latmax+0.01,0.01)
         else:
- lats = NX.arange(-90,90.1,0.1).astype(NX.Float32)
- xdelta = 0.1*(self.xmax-self.xmin)
- ydelta = 0.1*(self.ymax-self.ymin)
+ lats = NX.arange(-90,90.01,0.01)
+ xdelta = 0.01*(self.xmax-self.xmin)
+ ydelta = 0.01*(self.ymax-self.ymin)
         for merid in meridians:
             lons = merid*NX.ones(len(lats),NX.Float32)
             x,y = self(lons,lats)
@@ -1941,7 +1941,7 @@
         # search along edges of map to see if parallels intersect.
         # if so, find x,y location of intersection and draw a label there.
         if self.projection == 'cyl':
- dx = 0.01; dy = 0.01
+ dx = 0.001; dy = 0.001
         else:
             dx = 1000; dy = 1000
         if self.projection in ['moll','sinu','robin']:

This will make drawing of meridians and parallels slower, however.

-Jeff

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-124
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg

Hi Jeff,

Jesper: Hmm, I guess I never thought anyone would make a map that small.
I tweaked some of the parameters to make it work better (svn revision
3470). Here's the diff in case you just want to apply the patch manually:

Thanks for the patch. And apparantly you were right until now;-) In any case I
would guess that at some point basemap would need to be changed.

In shelf sea modelling we are now making setups with horizontal resolutions of
down to the order of hundreds of meters and global ocean models are not far
from this resolution either:

https://www.navo.navy.mil/nipr_2006/modeling.html

I am not entirely up to date with meteorological models but at least I know of
one limited area model that I use which has a resolution of 5 km.

This will make drawing of meridians and parallels slower, however.

What about making the resolution dependent on the size of the map if this is a
problem? I have a small method that I am using for creating nice contour
levels - although smarter methods definitely must exist. I have tried to
adapt it for producing what you need. If you decide to include something like
this please be aware that the Decimal(str(delta)) should probably be changed
(I don't think it will handle all cases well). Maybe it is faster simply to
increase the resolution as you have already done when it becomes necessary:

def _getInterval(minval, maxval, ninter):
  """Returns list which resolves minval to maxval with at least ninter
intervals."""
  import decimal
  import numpy as npy

  # Calculate interval between increments
  delta = (maxval-minval)/ninter
  n = decimal.Decimal(str(delta)).adjusted()
  delta = 10**n

  # Round off minimum and maximum values
  xmin = minval/10**n
  xmax = maxval/10**n
  xmin = (xmin - xmin % 10)*10**n
  xmax = (xmax + xmax % 10)*10**n

  values = npy.arange(xmin, xmax+delta, delta)
  return values

···

On Friday 06 July 2007 18:28, Jeff Whitaker wrote:

Jesper Larsen wrote:

Hi Jeff,

Jesper: Hmm, I guess I never thought anyone would make a map that small. I tweaked some of the parameters to make it work better (svn revision
3470). Here's the diff in case you just want to apply the patch manually:
    
Thanks for the patch. And apparantly you were right until now;-) In any case I would guess that at some point basemap would need to be changed.

In shelf sea modelling we are now making setups with horizontal resolutions of down to the order of hundreds of meters and global ocean models are not far from this resolution either:

https://www.navo.navy.mil/nipr_2006/modeling.html

I am not entirely up to date with meteorological models but at least I know of one limited area model that I use which has a resolution of 5 km.

This will make drawing of meridians and parallels slower, however.
    
What about making the resolution dependent on the size of the map if this is a problem? I have a small method that I am using for creating nice contour levels - although smarter methods definitely must exist. I have tried to adapt it for producing what you need. If you decide to include something like this please be aware that the Decimal(str(delta)) should probably be changed (I don't think it will handle all cases well). Maybe it is faster simply to increase the resolution as you have already done when it becomes necessary:

def _getInterval(minval, maxval, ninter):
  """Returns list which resolves minval to maxval with at least ninter intervals."""
  import decimal
  import numpy as npy

  # Calculate interval between increments
  delta = (maxval-minval)/ninter
  n = decimal.Decimal(str(delta)).adjusted()
  delta = 10**n

  # Round off minimum and maximum values
  xmin = minval/10**n
  xmax = maxval/10**n
  xmin = (xmin - xmin % 10)*10**n
  xmax = (xmax + xmax % 10)*10**n

  values = npy.arange(xmin, xmax+delta, delta)
  return values
  
Jespers: I've found a way to do it that doesn't appear to slow things down significantly. Try the latest svn and please let me know how it goes.

-Jeff

···

On Friday 06 July 2007 18:28, Jeff Whitaker wrote:

--
Jeffrey S. Whitaker Phone : (303)497-6313
NOAA/OAR/CDC R/PSD1 FAX : (303)497-6449
325 Broadway Boulder, CO, USA 80305-3328