Basemap continent colors

I have found a (possible) bug in Basemap - when using basemap.fillcontinents(), I see the chosen continent color only when the map I create includes some ocean. If I am in the interior of a continent (I've tested with North America and Asia), the continent color is white.

A code sample is below. My version information:
Basemap: 0.99.4
Matplotlib: 0.99.1.1
numpy: 1.4.0
Python: 2.6.4

To replicate my results, please try the following:
./maptest.py 37.894507 -121.816406 #map center is somewhere in the Bay Area in California
./maptest.py 41.880332 -100.47821 #map center is somewhere in Nebraska

The script creates a file called "output.png" in the calling directory. In the California case, I see the ocean as blue, and the land as a sort of annoying salmon color. In the Nebraska case, I see white with blue denoting the various rivers and lakes in the area.

Am I mis-using the basemap method calls in some way?

Thanks,

Mike

···

--------------------------------------------------------------------
#!/usr/bin/env python

import matplotlib
#use the non-interactive matplotlib setting
matplotlib.use('agg')
from mpl_toolkits.basemap import Basemap
import numpy as np
from pylab import *
import sys

clat = float(sys.argv[1])
clon = float(sys.argv[2])

figwidth = 5.4

bounds = (clon-4, clon+4, clat-4, clat+4)
dx = (bounds[1] - bounds[0])*111191 * np.cos(clat * np.pi/180)
dy = (bounds[3] - bounds[2])*111191
aspect = dy/dx
figheight = aspect * figwidth
  
fig = figure(figsize=(figwidth,figheight),edgecolor='g',facecolor='g')
ax1 = fig.add_axes([0,0,1.0,1.0])
mapcontour = Basemap(llcrnrlon=bounds[0],llcrnrlat=bounds[2],
                     urcrnrlon=bounds[1],urcrnrlat=bounds[3],
                     resolution='h',projection='merc',lat_ts=clat)
water_color = [.47,.60,.81]
mapcontour.drawrivers(color=water_color)
mapcontour.drawcountries(color='k',linewidth=2.0)
mapcontour.drawcoastlines()
mapcontour.fillcontinents(color=[1.0,0.8,0.8],lake_color=water_color)

plt.savefig('output.png')
--------------------------------------------------------------------

I have found a (possible) bug in Basemap - when using basemap.fillcontinents(), I see the chosen continent color only when the map I create includes some ocean. If I am in the interior of a continent (I've tested with North America and Asia), the continent color is white.
   
Michael: If there are no continent boundaries inside the map projection region, basemap does not draw anything (hence you see the axis background color). In that case, you should just set the axis background color to whatever you wanted the continent color to be.

-Jeff

···

On 5/10/10 2:21 PM, Michael Hearne wrote:

A code sample is below. My version information:
Basemap: 0.99.4
Matplotlib: 0.99.1.1
numpy: 1.4.0
Python: 2.6.4

To replicate my results, please try the following:
./maptest.py 37.894507 -121.816406 #map center is somewhere in the Bay Area in California
./maptest.py 41.880332 -100.47821 #map center is somewhere in Nebraska

The script creates a file called "output.png" in the calling directory. In the California case, I see the ocean as blue, and the land as a sort of annoying salmon color. In the Nebraska case, I see white with blue denoting the various rivers and lakes in the area.

Am I mis-using the basemap method calls in some way?

Thanks,

Mike

--------------------------------------------------------------------
#!/usr/bin/env python

import matplotlib
#use the non-interactive matplotlib setting
matplotlib.use('agg')
from mpl_toolkits.basemap import Basemap
import numpy as np
from pylab import *
import sys

clat = float(sys.argv[1])
clon = float(sys.argv[2])

figwidth = 5.4

bounds = (clon-4, clon+4, clat-4, clat+4)
dx = (bounds[1] - bounds[0])*111191 * np.cos(clat * np.pi/180)
dy = (bounds[3] - bounds[2])*111191
aspect = dy/dx
figheight = aspect * figwidth

fig = figure(figsize=(figwidth,figheight),edgecolor='g',facecolor='g')
ax1 = fig.add_axes([0,0,1.0,1.0])
mapcontour = Basemap(llcrnrlon=bounds[0],llcrnrlat=bounds[2],
                      urcrnrlon=bounds[1],urcrnrlat=bounds[3],
                      resolution='h',projection='merc',lat_ts=clat)
water_color = [.47,.60,.81]
mapcontour.drawrivers(color=water_color)
mapcontour.drawcountries(color='k',linewidth=2.0)
mapcontour.drawcoastlines()
mapcontour.fillcontinents(color=[1.0,0.8,0.8],lake_color=water_color)

plt.savefig('output.png')
--------------------------------------------------------------------

------------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Jeff - Thanks. Is there an easy way you know of to detect when there are no continent boundaries? I'm making these maps automatically, and so will not have the luxury of examining them to see where they are.

--Mike

···

On May 10, 2010, at 2:57 PM, Jeff Whitaker wrote:

On 5/10/10 2:21 PM, Michael Hearne wrote:

I have found a (possible) bug in Basemap - when using basemap.fillcontinents(), I see the chosen continent color only when the map I create includes some ocean. If I am in the interior of a continent (I've tested with North America and Asia), the continent color is white.
  
Michael: If there are no continent boundaries inside the map projection region, basemap does not draw anything (hence you see the axis background color). In that case, you should just set the axis background color to whatever you wanted the continent color to be.

-Jeff

A code sample is below. My version information:
Basemap: 0.99.4
Matplotlib: 0.99.1.1
numpy: 1.4.0
Python: 2.6.4

To replicate my results, please try the following:
./maptest.py 37.894507 -121.816406 #map center is somewhere in the Bay Area in California
./maptest.py 41.880332 -100.47821 #map center is somewhere in Nebraska

The script creates a file called "output.png" in the calling directory. In the California case, I see the ocean as blue, and the land as a sort of annoying salmon color. In the Nebraska case, I see white with blue denoting the various rivers and lakes in the area.

Am I mis-using the basemap method calls in some way?

Thanks,

Mike

--------------------------------------------------------------------
#!/usr/bin/env python

import matplotlib
#use the non-interactive matplotlib setting
matplotlib.use('agg')
from mpl_toolkits.basemap import Basemap
import numpy as np
from pylab import *
import sys

clat = float(sys.argv[1])
clon = float(sys.argv[2])

figwidth = 5.4

bounds = (clon-4, clon+4, clat-4, clat+4)
dx = (bounds[1] - bounds[0])*111191 * np.cos(clat * np.pi/180)
dy = (bounds[3] - bounds[2])*111191
aspect = dy/dx
figheight = aspect * figwidth

fig = figure(figsize=(figwidth,figheight),edgecolor='g',facecolor='g')
ax1 = fig.add_axes([0,0,1.0,1.0])
mapcontour = Basemap(llcrnrlon=bounds[0],llcrnrlat=bounds[2],
                     urcrnrlon=bounds[1],urcrnrlat=bounds[3],
                     resolution='h',projection='merc',lat_ts=clat)
water_color = [.47,.60,.81]
mapcontour.drawrivers(color=water_color)
mapcontour.drawcountries(color='k',linewidth=2.0)
mapcontour.drawcoastlines()
mapcontour.fillcontinents(color=[1.0,0.8,0.8],lake_color=water_color)

plt.savefig('output.png')
--------------------------------------------------------------------

------------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options
  

Jeff - Thanks. Is there an easy way you know of to detect when there are no continent boundaries? I'm making these maps automatically, and so will not have the luxury of examining them to see where they are.

--Mike
   
Mike: Unfortunately, there is no easy way to check since those computations are only done when you call fillcontinents. Here's a function that follows the logic in fillcontinents:

def all_land(map):
     for poly,type in zip(map.coastpolygons, map.coastpolygontypes):
         if type == 1:
             x, y = poly
             xa = np.array(x,np.float32)
             ya = np.array(y,np.float32)
             # check to see if all four corners of domain in polygon (if so,
             # don't draw since it will just fill in the whole map).
             delx = 10; dely = 10
             if map.projection in ['cyl']:
                 delx = 0.1
                 dely = 0.1
             test1 = np.fabs(xa-map.urcrnrx) < delx
             test2 = np.fabs(xa-map.llcrnrx) < delx
             test3 = np.fabs(ya-map.urcrnry) < dely
             test4 = np.fabs(ya-map.llcrnry) < dely
             hasp1 = np.sum(test1*test3)
             hasp2 = np.sum(test2*test3)
             hasp4 = np.sum(test2*test4)
             hasp3 = np.sum(test1*test4)
             if not hasp1 or not hasp2 or not hasp3 or not hasp4:
                 allin = False
             else:
                 allin = True
             return allin

If you pass this function the basemap instance, it should return True if no coastline polygons will be drawn.

-Jeff

···

On 5/11/10 8:02 AM, Michael Hearne wrote:

On May 10, 2010, at 2:57 PM, Jeff Whitaker wrote:

On 5/10/10 2:21 PM, Michael Hearne wrote:
     

I have found a (possible) bug in Basemap - when using basemap.fillcontinents(), I see the chosen continent color only when the map I create includes some ocean. If I am in the interior of a continent (I've tested with North America and Asia), the continent color is white.

Michael: If there are no continent boundaries inside the map projection region, basemap does not draw anything (hence you see the axis background color). In that case, you should just set the axis background color to whatever you wanted the continent color to be.

-Jeff
     

A code sample is below. My version information:
Basemap: 0.99.4
Matplotlib: 0.99.1.1
numpy: 1.4.0
Python: 2.6.4

To replicate my results, please try the following:
./maptest.py 37.894507 -121.816406 #map center is somewhere in the Bay Area in California
./maptest.py 41.880332 -100.47821 #map center is somewhere in Nebraska

The script creates a file called "output.png" in the calling directory. In the California case, I see the ocean as blue, and the land as a sort of annoying salmon color. In the Nebraska case, I see white with blue denoting the various rivers and lakes in the area.

Am I mis-using the basemap method calls in some way?

Thanks,

Mike

--------------------------------------------------------------------
#!/usr/bin/env python

import matplotlib
#use the non-interactive matplotlib setting
matplotlib.use('agg')
from mpl_toolkits.basemap import Basemap
import numpy as np
from pylab import *
import sys

clat = float(sys.argv[1])
clon = float(sys.argv[2])

figwidth = 5.4

bounds = (clon-4, clon+4, clat-4, clat+4)
dx = (bounds[1] - bounds[0])*111191 * np.cos(clat * np.pi/180)
dy = (bounds[3] - bounds[2])*111191
aspect = dy/dx
figheight = aspect * figwidth

fig = figure(figsize=(figwidth,figheight),edgecolor='g',facecolor='g')
ax1 = fig.add_axes([0,0,1.0,1.0])
mapcontour = Basemap(llcrnrlon=bounds[0],llcrnrlat=bounds[2],
                      urcrnrlon=bounds[1],urcrnrlat=bounds[3],
                      resolution='h',projection='merc',lat_ts=clat)
water_color = [.47,.60,.81]
mapcontour.drawrivers(color=water_color)
mapcontour.drawcountries(color='k',linewidth=2.0)
mapcontour.drawcoastlines()
mapcontour.fillcontinents(color=[1.0,0.8,0.8],lake_color=water_color)

plt.savefig('output.png')
--------------------------------------------------------------------

------------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

--
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-113
Boulder, CO, USA 80303-3328 Web : Jeffrey S. Whitaker: NOAA Physical Sciences Laboratory

Jeff - That's great, thanks! For future releases, is there a reason why fillcontinents() couldn't do the logic for the user - i.e., if the continent fills the figure, paint it with the user's desired color? I think that's less surprising than the way it works now.

--Mike

···

On May 11, 2010, at 2:22 PM, Jeff Whitaker wrote:

On 5/11/10 8:02 AM, Michael Hearne wrote:

Jeff - Thanks. Is there an easy way you know of to detect when there are no continent boundaries? I'm making these maps automatically, and so will not have the luxury of examining them to see where they are.

--Mike
  
Mike: Unfortunately, there is no easy way to check since those computations are only done when you call fillcontinents. Here's a function that follows the logic in fillcontinents:

def all_land(map):
   for poly,type in zip(map.coastpolygons, map.coastpolygontypes):
       if type == 1:
           x, y = poly
           xa = np.array(x,np.float32)
           ya = np.array(y,np.float32)
           # check to see if all four corners of domain in polygon (if so,
           # don't draw since it will just fill in the whole map).
           delx = 10; dely = 10
           if map.projection in ['cyl']:
               delx = 0.1
               dely = 0.1
           test1 = np.fabs(xa-map.urcrnrx) < delx
           test2 = np.fabs(xa-map.llcrnrx) < delx
           test3 = np.fabs(ya-map.urcrnry) < dely
           test4 = np.fabs(ya-map.llcrnry) < dely
           hasp1 = np.sum(test1*test3)
           hasp2 = np.sum(test2*test3)
           hasp4 = np.sum(test2*test4)
           hasp3 = np.sum(test1*test4)
           if not hasp1 or not hasp2 or not hasp3 or not hasp4:
               allin = False
           else:
               allin = True
           return allin

If you pass this function the basemap instance, it should return True if no coastline polygons will be drawn.

-Jeff

On May 10, 2010, at 2:57 PM, Jeff Whitaker wrote:

On 5/10/10 2:21 PM, Michael Hearne wrote:
    

I have found a (possible) bug in Basemap - when using basemap.fillcontinents(), I see the chosen continent color only when the map I create includes some ocean. If I am in the interior of a continent (I've tested with North America and Asia), the continent color is white.

Michael: If there are no continent boundaries inside the map projection region, basemap does not draw anything (hence you see the axis background color). In that case, you should just set the axis background color to whatever you wanted the continent color to be.

-Jeff
    

A code sample is below. My version information:
Basemap: 0.99.4
Matplotlib: 0.99.1.1
numpy: 1.4.0
Python: 2.6.4

To replicate my results, please try the following:
./maptest.py 37.894507 -121.816406 #map center is somewhere in the Bay Area in California
./maptest.py 41.880332 -100.47821 #map center is somewhere in Nebraska

The script creates a file called "output.png" in the calling directory. In the California case, I see the ocean as blue, and the land as a sort of annoying salmon color. In the Nebraska case, I see white with blue denoting the various rivers and lakes in the area.

Am I mis-using the basemap method calls in some way?

Thanks,

Mike

--------------------------------------------------------------------
#!/usr/bin/env python

import matplotlib
#use the non-interactive matplotlib setting
matplotlib.use('agg')
from mpl_toolkits.basemap import Basemap
import numpy as np
from pylab import *
import sys

clat = float(sys.argv[1])
clon = float(sys.argv[2])

figwidth = 5.4

bounds = (clon-4, clon+4, clat-4, clat+4)
dx = (bounds[1] - bounds[0])*111191 * np.cos(clat * np.pi/180)
dy = (bounds[3] - bounds[2])*111191
aspect = dy/dx
figheight = aspect * figwidth

fig = figure(figsize=(figwidth,figheight),edgecolor='g',facecolor='g')
ax1 = fig.add_axes([0,0,1.0,1.0])
mapcontour = Basemap(llcrnrlon=bounds[0],llcrnrlat=bounds[2],
                     urcrnrlon=bounds[1],urcrnrlat=bounds[3],
                     resolution='h',projection='merc',lat_ts=clat)
water_color = [.47,.60,.81]
mapcontour.drawrivers(color=water_color)
mapcontour.drawcountries(color='k',linewidth=2.0)
mapcontour.drawcoastlines()
mapcontour.fillcontinents(color=[1.0,0.8,0.8],lake_color=water_color)

plt.savefig('output.png')
--------------------------------------------------------------------

------------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

--
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-113
Boulder, CO, USA 80303-3328 Web : Jeffrey S. Whitaker: NOAA Physical Sciences Laboratory

Jeff - That's great, thanks! For future releases, is there a reason why fillcontinents() couldn't do the logic for the user - i.e., if the continent fills the figure, paint it with the user's desired color? I think that's less surprising than the way it works now.

--Mike
   
Mike: You're right, it is surprising behavior. The reason I did it that way was because sometimes the polygon filling algorithm gets confused when all four corners of the domain are in the polygon and fills the whole map (even when it shouldn't). Since the cure is probably worse than the disease in this case, I've turned this off in svn, so your example works as expected.

-Jeff

···

On 5/12/10 7:37 AM, Michael Hearne wrote:

On May 11, 2010, at 2:22 PM, Jeff Whitaker wrote:

On 5/11/10 8:02 AM, Michael Hearne wrote:
     

Jeff - Thanks. Is there an easy way you know of to detect when there are no continent boundaries? I'm making these maps automatically, and so will not have the luxury of examining them to see where they are.

--Mike

Mike: Unfortunately, there is no easy way to check since those computations are only done when you call fillcontinents. Here's a function that follows the logic in fillcontinents:

def all_land(map):
    for poly,type in zip(map.coastpolygons, map.coastpolygontypes):
        if type == 1:
            x, y = poly
            xa = np.array(x,np.float32)
            ya = np.array(y,np.float32)
            # check to see if all four corners of domain in polygon (if so,
            # don't draw since it will just fill in the whole map).
            delx = 10; dely = 10
            if map.projection in ['cyl']:
                delx = 0.1
                dely = 0.1
            test1 = np.fabs(xa-map.urcrnrx)< delx
            test2 = np.fabs(xa-map.llcrnrx)< delx
            test3 = np.fabs(ya-map.urcrnry)< dely
            test4 = np.fabs(ya-map.llcrnry)< dely
            hasp1 = np.sum(test1*test3)
            hasp2 = np.sum(test2*test3)
            hasp4 = np.sum(test2*test4)
            hasp3 = np.sum(test1*test4)
            if not hasp1 or not hasp2 or not hasp3 or not hasp4:
                allin = False
            else:
                allin = True
            return allin

If you pass this function the basemap instance, it should return True if no coastline polygons will be drawn.

-Jeff

On May 10, 2010, at 2:57 PM, Jeff Whitaker wrote:

On 5/10/10 2:21 PM, Michael Hearne wrote:

I have found a (possible) bug in Basemap - when using basemap.fillcontinents(), I see the chosen continent color only when the map I create includes some ocean. If I am in the interior of a continent (I've tested with North America and Asia), the continent color is white.

Michael: If there are no continent boundaries inside the map projection region, basemap does not draw anything (hence you see the axis background color). In that case, you should just set the axis background color to whatever you wanted the continent color to be.

-Jeff

A code sample is below. My version information:
Basemap: 0.99.4
Matplotlib: 0.99.1.1
numpy: 1.4.0
Python: 2.6.4

To replicate my results, please try the following:
./maptest.py 37.894507 -121.816406 #map center is somewhere in the Bay Area in California
./maptest.py 41.880332 -100.47821 #map center is somewhere in Nebraska

The script creates a file called "output.png" in the calling directory. In the California case, I see the ocean as blue, and the land as a sort of annoying salmon color. In the Nebraska case, I see white with blue denoting the various rivers and lakes in the area.

Am I mis-using the basemap method calls in some way?

Thanks,

Mike

--------------------------------------------------------------------
#!/usr/bin/env python

import matplotlib
#use the non-interactive matplotlib setting
matplotlib.use('agg')
from mpl_toolkits.basemap import Basemap
import numpy as np
from pylab import *
import sys

clat = float(sys.argv[1])
clon = float(sys.argv[2])

figwidth = 5.4

bounds = (clon-4, clon+4, clat-4, clat+4)
dx = (bounds[1] - bounds[0])*111191 * np.cos(clat * np.pi/180)
dy = (bounds[3] - bounds[2])*111191
aspect = dy/dx
figheight = aspect * figwidth

fig = figure(figsize=(figwidth,figheight),edgecolor='g',facecolor='g')
ax1 = fig.add_axes([0,0,1.0,1.0])
mapcontour = Basemap(llcrnrlon=bounds[0],llcrnrlat=bounds[2],
                      urcrnrlon=bounds[1],urcrnrlat=bounds[3],
                      resolution='h',projection='merc',lat_ts=clat)
water_color = [.47,.60,.81]
mapcontour.drawrivers(color=water_color)
mapcontour.drawcountries(color='k',linewidth=2.0)
mapcontour.drawcoastlines()
mapcontour.fillcontinents(color=[1.0,0.8,0.8],lake_color=water_color)

plt.savefig('output.png')
--------------------------------------------------------------------

------------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

--
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-113
Boulder, CO, USA 80303-3328 Web : Jeffrey S. Whitaker: NOAA Physical Sciences Laboratory

--
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-113
Boulder, CO, USA 80303-3328 Web : Jeffrey S. Whitaker: NOAA Physical Sciences Laboratory