Re: [Matplotlib-users] basemap scalebar

2008-03-06 Thread Stephane Raynaud
Hi,

this scalebar is a really good idea!

However, I suggest that all parameters must be optional:
- The position could be by default somewhere in the lower left corner
(for example). It may be interesting to find a best position using
the algo of legend.
- Then length could be estimated from automatically from the map coordinates.


On Tue, Mar 4, 2008 at 3:47 PM, Michael Hearne [EMAIL PROTECTED] wrote:
  Jeff - I think the way GMT does it would be okay - they have a latitude of
 true scale, which I usually choose as the center latitude of the map.

 I was thinking we should allow people to choose the simple or fancy
 options.  Do you think it will be okay to have the height of the bar and the
 text offset be relative to the length of it?  I suppose if the height
 becomes a problem, people could use the yoffset keyword...

 --Mike


 On Mar 4, 2008, at 6:05 AM, Jeff Whitaker wrote:

 Michael Hearne wrote:
 Jeff - That would replicate the simple scale-bar from GMT.  Below is my
 not-complete attempt at replicating the fancy scale bar.  It would need
 some options for specifying different units (miles, nautical miles, etc.)
 and perhaps some more attention to spacing of the text from the scale bar
 and tick marks...

 --Mike

 Mike:  Very nice!  Do you want the scale to show the true distance on the
 earth (in which case the labels will vary depending on where the label is
 placed), or the distance in map projection coordinates (in which case the
 labels are constant)?  Or perhaps a lat/lon value could be given to specify
 where the scale is true?

 -Jeff

 from numpy import *
 from matplotlib.toolkits.basemap import Basemap, pyproj
 from pylab import *
 # add drawscale method to Basemap class.
 class Basemap2(Basemap):
def drawscale(self,lon,lat,length,yoffset=None):
draw a fancy map scale from lon-length/2,lat-yoffset to
lon-length/2,lat-yoffset, label it with actual distance in km
length = length*1000 #input length is km

#we need 5 sets of x coordinates (in map units)
#center of scale
xc,yc = self(lon,lat)
#left edge of scale
lon1,lat1 = self(xc-length/2,yc,inverse=True)
x1,y1 = self(lon1,lat1)
#quarter scale
lon2,lat2 = self(xc-length/4,yc,inverse=True)
x2,y2 = self(lon2,lat2)
#three quarter scale
lon3,lat3 = self(xc+length/4,yc,inverse=True)
x3,y3 = self(lon3,lat3)
#right edge of scale
lon4,lat4 = self(xc+length/2,yc,inverse=True)
x4,y4 = self(lon4,lat4)
   if yoffset is None: yoffset = 0.1*length

#plot top line
ytop = yc+yoffset/2
ybottom = yc-yoffset/2
ytick = ybottom - yoffset/2
ytext = ytick - yoffset/2
m.plot([x1,x4],[ytop,ytop],color='k')
#plot bottom line
m.plot([x1,x4],[ybottom,ybottom],color='k')
#plot left edge
m.plot([x1,x1],[ybottom,ytop],color='k')
#plot right edge
m.plot([x4,x4],[ybottom,ytop],color='k')

#make a filled black box from left edge to 1/4 way across
fill([x1,x2,x2,x1,x1],[ytop,ytop,ybottom,ybottom,ytop],'k')
#make a filled white box from 1/4 way across to 1/2 way across
fill([x2,xc,xc,x2,x2],[ytop,ytop,ybottom,ybottom,ytop],'w')
#make a filled white box from 1/2 way across to 3/4 way across
fill([xc,x3,x3,xc,xc],[ytop,ytop,ybottom,ybottom,ytop],'k')
#make a filled white box from 3/4 way across to end
fill([x3,x4,x4,x3,x3],[ytop,ytop,ybottom,ybottom,ytop],'w')
   #plot 3 tick marks at left edge, center, and right edge
m.plot([x1,x1],[ytick,ybottom],color='k')
m.plot([xc,xc],[ytick,ybottom],color='k')
m.plot([x4,x4],[ytick,ybottom],color='k')

#label 3 tick marks
text(x1,ytext,'%d' % (0),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
text(xc,ytext,'%d' % (round((length/2)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
text(x4,ytext,'%d' % (round((length)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)

#put units on top
text(xc,ytop+yoffset/2,'km',\
horizontalalignment='center',\
verticalalignment='bottom',\
fontsize=9)

 # setup of basemap ('lcc' = lambert conformal conic).
 # use major and minor sphere radii from WGS84 ellipsoid.
 m =
 Basemap2(llcrnrlon=-145.5,llcrnrlat=1.,urcrnrlon=-2.566,urcrnrlat=46.352,\
  rsphere=(6378137.00,6356752.3142),\
  resolution='l',area_thresh=1000.,projection='lcc',\
  lat_1=50.,lon_0=-107.)
 # draw coastlines and political boundaries.
 m.drawcoastlines()
 m.fillcontinents()
 # draw parallels and meridians.
 # label on left, right and bottom of map.
 m.drawparallels(arange(0.,80,20.),labels=[1,1,0,1])
 m.drawmeridians(arange(10.,360.,30.),labels=[1,1,0,1])
 # draw a line from x1,y to x2,y and label it 

Re: [Matplotlib-users] basemap scalebar

2008-03-06 Thread Jeff Whitaker
Stephane Raynaud wrote:
 Hi,

 this scalebar is a really good idea!

 However, I suggest that all parameters must be optional:
 - The position could be by default somewhere in the lower left corner
 (for example). It may be interesting to find a best position using
 the algo of legend.
 - Then length could be estimated from automatically from the map coordinates.


   
Stephane:  While I agree it would be nice to be able to just say 'give 
me a scalebar', I don't think having Basemap choose a default location 
and size would be very useful.  You want the scalebar to be where there 
is nothing else drawn on the map, and this will be different in every 
case.  Plus, you probably want the length to be a nice round number, not 
an arbitrary fraction of the map domain.

-Jeff
 On Tue, Mar 4, 2008 at 3:47 PM, Michael Hearne [EMAIL PROTECTED] wrote:
   
  Jeff - I think the way GMT does it would be okay - they have a latitude of
 true scale, which I usually choose as the center latitude of the map.

 I was thinking we should allow people to choose the simple or fancy
 options.  Do you think it will be okay to have the height of the bar and the
 text offset be relative to the length of it?  I suppose if the height
 becomes a problem, people could use the yoffset keyword...

 --Mike


 On Mar 4, 2008, at 6:05 AM, Jeff Whitaker wrote:

 Michael Hearne wrote:
 Jeff - That would replicate the simple scale-bar from GMT.  Below is my
 not-complete attempt at replicating the fancy scale bar.  It would need
 some options for specifying different units (miles, nautical miles, etc.)
 and perhaps some more attention to spacing of the text from the scale bar
 and tick marks...

 --Mike

 Mike:  Very nice!  Do you want the scale to show the true distance on the
 earth (in which case the labels will vary depending on where the label is
 placed), or the distance in map projection coordinates (in which case the
 labels are constant)?  Or perhaps a lat/lon value could be given to specify
 where the scale is true?

 -Jeff

 from numpy import *
 from matplotlib.toolkits.basemap import Basemap, pyproj
 from pylab import *
 # add drawscale method to Basemap class.
 class Basemap2(Basemap):
def drawscale(self,lon,lat,length,yoffset=None):
draw a fancy map scale from lon-length/2,lat-yoffset to
lon-length/2,lat-yoffset, label it with actual distance in km
length = length*1000 #input length is km

#we need 5 sets of x coordinates (in map units)
#center of scale
xc,yc = self(lon,lat)
#left edge of scale
lon1,lat1 = self(xc-length/2,yc,inverse=True)
x1,y1 = self(lon1,lat1)
#quarter scale
lon2,lat2 = self(xc-length/4,yc,inverse=True)
x2,y2 = self(lon2,lat2)
#three quarter scale
lon3,lat3 = self(xc+length/4,yc,inverse=True)
x3,y3 = self(lon3,lat3)
#right edge of scale
lon4,lat4 = self(xc+length/2,yc,inverse=True)
x4,y4 = self(lon4,lat4)
   if yoffset is None: yoffset = 0.1*length

#plot top line
ytop = yc+yoffset/2
ybottom = yc-yoffset/2
ytick = ybottom - yoffset/2
ytext = ytick - yoffset/2
m.plot([x1,x4],[ytop,ytop],color='k')
#plot bottom line
m.plot([x1,x4],[ybottom,ybottom],color='k')
#plot left edge
m.plot([x1,x1],[ybottom,ytop],color='k')
#plot right edge
m.plot([x4,x4],[ybottom,ytop],color='k')

#make a filled black box from left edge to 1/4 way across
fill([x1,x2,x2,x1,x1],[ytop,ytop,ybottom,ybottom,ytop],'k')
#make a filled white box from 1/4 way across to 1/2 way across
fill([x2,xc,xc,x2,x2],[ytop,ytop,ybottom,ybottom,ytop],'w')
#make a filled white box from 1/2 way across to 3/4 way across
fill([xc,x3,x3,xc,xc],[ytop,ytop,ybottom,ybottom,ytop],'k')
#make a filled white box from 3/4 way across to end
fill([x3,x4,x4,x3,x3],[ytop,ytop,ybottom,ybottom,ytop],'w')
   #plot 3 tick marks at left edge, center, and right edge
m.plot([x1,x1],[ytick,ybottom],color='k')
m.plot([xc,xc],[ytick,ybottom],color='k')
m.plot([x4,x4],[ytick,ybottom],color='k')

#label 3 tick marks
text(x1,ytext,'%d' % (0),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
text(xc,ytext,'%d' % (round((length/2)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
text(x4,ytext,'%d' % (round((length)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)

#put units on top
text(xc,ytop+yoffset/2,'km',\
horizontalalignment='center',\
verticalalignment='bottom',\
fontsize=9)

 # setup of basemap ('lcc' = lambert conformal conic).
 # use major and minor sphere radii from WGS84 ellipsoid.
 m =
 

Re: [Matplotlib-users] basemap scalebar

2008-03-06 Thread Stephane Raynaud
On Thu, Mar 6, 2008 at 6:15 PM, Jeff Whitaker [EMAIL PROTECTED] wrote:
 Stephane Raynaud wrote:
   Hi,
  
   this scalebar is a really good idea!
  
   However, I suggest that all parameters must be optional:
   - The position could be by default somewhere in the lower left corner
   (for example). It may be interesting to find a best position using
   the algo of legend.
   - Then length could be estimated from automatically from the map 
 coordinates.
  
  
  
  Stephane:  While I agree it would be nice to be able to just say 'give
  me a scalebar', I don't think having Basemap choose a default location
  and size would be very useful.  You want the scalebar to be where there
  is nothing else drawn on the map, and this will be different in every
  case.

Sure, but the algorithm used by legend tries to put the legend where
there is nothing drawn.


 Plus, you probably want the length to be a nice round number, not
  an arbitrary fraction of the map domain.

I was not thinking about a simple fraction, but a nice length taken
within values derived from a Locator scaled by a fraction on the map
domain.



  -Jeff


  On Tue, Mar 4, 2008 at 3:47 PM, Michael Hearne [EMAIL PROTECTED] wrote:
  
Jeff - I think the way GMT does it would be okay - they have a latitude 
 of
   true scale, which I usually choose as the center latitude of the map.
  
   I was thinking we should allow people to choose the simple or fancy
   options.  Do you think it will be okay to have the height of the bar and 
 the
   text offset be relative to the length of it?  I suppose if the height
   becomes a problem, people could use the yoffset keyword...
  
   --Mike
  
  
   On Mar 4, 2008, at 6:05 AM, Jeff Whitaker wrote:
  
   Michael Hearne wrote:
   Jeff - That would replicate the simple scale-bar from GMT.  Below is my
   not-complete attempt at replicating the fancy scale bar.  It would need
   some options for specifying different units (miles, nautical miles, etc.)
   and perhaps some more attention to spacing of the text from the scale bar
   and tick marks...
  
   --Mike
  
   Mike:  Very nice!  Do you want the scale to show the true distance on the
   earth (in which case the labels will vary depending on where the label is
   placed), or the distance in map projection coordinates (in which case the
   labels are constant)?  Or perhaps a lat/lon value could be given to 
 specify
   where the scale is true?
  
   -Jeff
  
   from numpy import *
   from matplotlib.toolkits.basemap import Basemap, pyproj
   from pylab import *
   # add drawscale method to Basemap class.
   class Basemap2(Basemap):
  def drawscale(self,lon,lat,length,yoffset=None):
  draw a fancy map scale from lon-length/2,lat-yoffset to
  lon-length/2,lat-yoffset, label it with actual distance in km
  length = length*1000 #input length is km
  
  #we need 5 sets of x coordinates (in map units)
  #center of scale
  xc,yc = self(lon,lat)
  #left edge of scale
  lon1,lat1 = self(xc-length/2,yc,inverse=True)
  x1,y1 = self(lon1,lat1)
  #quarter scale
  lon2,lat2 = self(xc-length/4,yc,inverse=True)
  x2,y2 = self(lon2,lat2)
  #three quarter scale
  lon3,lat3 = self(xc+length/4,yc,inverse=True)
  x3,y3 = self(lon3,lat3)
  #right edge of scale
  lon4,lat4 = self(xc+length/2,yc,inverse=True)
  x4,y4 = self(lon4,lat4)
 if yoffset is None: yoffset = 0.1*length
  
  #plot top line
  ytop = yc+yoffset/2
  ybottom = yc-yoffset/2
  ytick = ybottom - yoffset/2
  ytext = ytick - yoffset/2
  m.plot([x1,x4],[ytop,ytop],color='k')
  #plot bottom line
  m.plot([x1,x4],[ybottom,ybottom],color='k')
  #plot left edge
  m.plot([x1,x1],[ybottom,ytop],color='k')
  #plot right edge
  m.plot([x4,x4],[ybottom,ytop],color='k')
  
  #make a filled black box from left edge to 1/4 way across
  fill([x1,x2,x2,x1,x1],[ytop,ytop,ybottom,ybottom,ytop],'k')
  #make a filled white box from 1/4 way across to 1/2 way across
  fill([x2,xc,xc,x2,x2],[ytop,ytop,ybottom,ybottom,ytop],'w')
  #make a filled white box from 1/2 way across to 3/4 way across
  fill([xc,x3,x3,xc,xc],[ytop,ytop,ybottom,ybottom,ytop],'k')
  #make a filled white box from 3/4 way across to end
  fill([x3,x4,x4,x3,x3],[ytop,ytop,ybottom,ybottom,ytop],'w')
 #plot 3 tick marks at left edge, center, and right edge
  m.plot([x1,x1],[ytick,ybottom],color='k')
  m.plot([xc,xc],[ytick,ybottom],color='k')
  m.plot([x4,x4],[ytick,ybottom],color='k')
  
  #label 3 tick marks
  text(x1,ytext,'%d' % (0),\
  horizontalalignment='center',\
  verticalalignment='top',\
  fontsize=9)
  text(xc,ytext,'%d' % (round((length/2)/1000)),\
  

Re: [Matplotlib-users] basemap scalebar

2008-03-06 Thread Jeff Whitaker
Stephane Raynaud wrote:
 On Thu, Mar 6, 2008 at 6:15 PM, Jeff Whitaker [EMAIL PROTECTED] wrote:
   
 Stephane Raynaud wrote:
   Hi,
  
   this scalebar is a really good idea!
  
   However, I suggest that all parameters must be optional:
   - The position could be by default somewhere in the lower left corner
   (for example). It may be interesting to find a best position using
   the algo of legend.
   - Then length could be estimated from automatically from the map 
 coordinates.
  
  
  
  Stephane:  While I agree it would be nice to be able to just say 'give
  me a scalebar', I don't think having Basemap choose a default location
  and size would be very useful.  You want the scalebar to be where there
  is nothing else drawn on the map, and this will be different in every
  case.
 

 Sure, but the algorithm used by legend tries to put the legend where
 there is nothing drawn.


   
 Plus, you probably want the length to be a nice round number, not
  an arbitrary fraction of the map domain.
 

 I was not thinking about a simple fraction, but a nice length taken
 within values derived from a Locator scaled by a fraction on the map
 domain.

   

Stephane:  Sounds reasonable, but I don't have time to work on this 
now.  Patches are always welcome! (including your caching module)

-Jeff

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


-
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/
___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] basemap scalebar

2008-03-04 Thread Jeff Whitaker
Michael Hearne wrote:
 Jeff - That would replicate the simple scale-bar from GMT.  Below is 
 my not-complete attempt at replicating the fancy scale bar.  It 
 would need some options for specifying different units (miles, 
 nautical miles, etc.) and perhaps some more attention to spacing of 
 the text from the scale bar and tick marks...

 --Mike

Mike:  Very nice!  Do you want the scale to show the true distance on 
the earth (in which case the labels will vary depending on where the 
label is placed), or the distance in map projection coordinates (in 
which case the labels are constant)?  Or perhaps a lat/lon value could 
be given to specify where the scale is true?

-Jeff

 from numpy import *
 from matplotlib.toolkits.basemap import Basemap, pyproj
 from pylab import *
 # add drawscale method to Basemap class.
 class Basemap2(Basemap):
def drawscale(self,lon,lat,length,yoffset=None):
draw a fancy map scale from lon-length/2,lat-yoffset to
lon-length/2,lat-yoffset, label it with actual distance in km
length = length*1000 #input length is km

#we need 5 sets of x coordinates (in map units)
#center of scale
xc,yc = self(lon,lat)
#left edge of scale
lon1,lat1 = self(xc-length/2,yc,inverse=True)
x1,y1 = self(lon1,lat1)
#quarter scale
lon2,lat2 = self(xc-length/4,yc,inverse=True)
x2,y2 = self(lon2,lat2)
#three quarter scale
lon3,lat3 = self(xc+length/4,yc,inverse=True)
x3,y3 = self(lon3,lat3)
#right edge of scale
lon4,lat4 = self(xc+length/2,yc,inverse=True)
x4,y4 = self(lon4,lat4)

if yoffset is None: yoffset = 0.1*length

#plot top line
ytop = yc+yoffset/2
ybottom = yc-yoffset/2
ytick = ybottom - yoffset/2
ytext = ytick - yoffset/2
m.plot([x1,x4],[ytop,ytop],color='k')
#plot bottom line
m.plot([x1,x4],[ybottom,ybottom],color='k')
#plot left edge
m.plot([x1,x1],[ybottom,ytop],color='k')
#plot right edge
m.plot([x4,x4],[ybottom,ytop],color='k')

#make a filled black box from left edge to 1/4 way across
fill([x1,x2,x2,x1,x1],[ytop,ytop,ybottom,ybottom,ytop],'k')
#make a filled white box from 1/4 way across to 1/2 way across
fill([x2,xc,xc,x2,x2],[ytop,ytop,ybottom,ybottom,ytop],'w')
#make a filled white box from 1/2 way across to 3/4 way across
fill([xc,x3,x3,xc,xc],[ytop,ytop,ybottom,ybottom,ytop],'k')
#make a filled white box from 3/4 way across to end
fill([x3,x4,x4,x3,x3],[ytop,ytop,ybottom,ybottom,ytop],'w')

#plot 3 tick marks at left edge, center, and right edge
m.plot([x1,x1],[ytick,ybottom],color='k')
m.plot([xc,xc],[ytick,ybottom],color='k')
m.plot([x4,x4],[ytick,ybottom],color='k')

#label 3 tick marks
text(x1,ytext,'%d' % (0),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
text(xc,ytext,'%d' % (round((length/2)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
text(x4,ytext,'%d' % (round((length)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)

#put units on top
text(xc,ytop+yoffset/2,'km',\
horizontalalignment='center',\
verticalalignment='bottom',\
fontsize=9)

 # setup of basemap ('lcc' = lambert conformal conic).
 # use major and minor sphere radii from WGS84 ellipsoid.
 m = 
 Basemap2(llcrnrlon=-145.5,llcrnrlat=1.,urcrnrlon=-2.566,urcrnrlat=46.352,\
  rsphere=(6378137.00,6356752.3142),\
  resolution='l',area_thresh=1000.,projection='lcc',\
  lat_1=50.,lon_0=-107.)
 # draw coastlines and political boundaries.
 m.drawcoastlines()
 m.fillcontinents()
 # draw parallels and meridians.
 # label on left, right and bottom of map.
 m.drawparallels(arange(0.,80,20.),labels=[1,1,0,1])
 m.drawmeridians(arange(10.,360.,30.),labels=[1,1,0,1])
 # draw a line from x1,y to x2,y and label it with distance in km.
 length = 3000 #kilometers
 x1,y1 = 0.25*m.xmax, 0.25*m.ymax
 lon1,lat1 = m(x1,y1,inverse=True)
 m.drawscale(lon1,lat1,length)
 title('a fancy map scale')
 show()




 --
 Michael Hearne
 [EMAIL PROTECTED] mailto:[EMAIL PROTECTED]
 (303) 273-8620
 USGS National Earthquake Information Center
 1711 Illinois St. Golden CO 80401
 Senior Software Engineer
 Synergetics, Inc.
 --




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


-
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.

Re: [Matplotlib-users] basemap scalebar

2008-03-04 Thread Michael Hearne
Jeff - I think the way GMT does it would be okay - they have a  
latitude of true scale, which I usually choose as the center latitude  
of the map.


I was thinking we should allow people to choose the simple or  
fancy options.  Do you think it will be okay to have the height of  
the bar and the text offset be relative to the length of it?  I  
suppose if the height becomes a problem, people could use the yoffset  
keyword...


--Mike
On Mar 4, 2008, at 6:05 AM, Jeff Whitaker wrote:


Michael Hearne wrote:
Jeff - That would replicate the simple scale-bar from GMT.   
Below is my not-complete attempt at replicating the fancy scale  
bar.  It would need some options for specifying different units  
(miles, nautical miles, etc.) and perhaps some more attention to  
spacing of the text from the scale bar and tick marks...


--Mike


Mike:  Very nice!  Do you want the scale to show the true distance  
on the earth (in which case the labels will vary depending on where  
the label is placed), or the distance in map projection coordinates  
(in which case the labels are constant)?  Or perhaps a lat/lon  
value could be given to specify where the scale is true?


-Jeff


from numpy import *
from matplotlib.toolkits.basemap import Basemap, pyproj
from pylab import *
# add drawscale method to Basemap class.
class Basemap2(Basemap):
   def drawscale(self,lon,lat,length,yoffset=None):
   draw a fancy map scale from lon-length/2,lat-yoffset to
   lon-length/2,lat-yoffset, label it with actual distance in  
km

   length = length*1000 #input length is km

   #we need 5 sets of x coordinates (in map units)
   #center of scale
   xc,yc = self(lon,lat)
   #left edge of scale
   lon1,lat1 = self(xc-length/2,yc,inverse=True)
   x1,y1 = self(lon1,lat1)
   #quarter scale
   lon2,lat2 = self(xc-length/4,yc,inverse=True)
   x2,y2 = self(lon2,lat2)
   #three quarter scale
   lon3,lat3 = self(xc+length/4,yc,inverse=True)
   x3,y3 = self(lon3,lat3)
   #right edge of scale
   lon4,lat4 = self(xc+length/2,yc,inverse=True)
   x4,y4 = self(lon4,lat4)
  if yoffset is None: yoffset = 0.1*length

   #plot top line
   ytop = yc+yoffset/2
   ybottom = yc-yoffset/2
   ytick = ybottom - yoffset/2
   ytext = ytick - yoffset/2
   m.plot([x1,x4],[ytop,ytop],color='k')
   #plot bottom line
   m.plot([x1,x4],[ybottom,ybottom],color='k')
   #plot left edge
   m.plot([x1,x1],[ybottom,ytop],color='k')
   #plot right edge
   m.plot([x4,x4],[ybottom,ytop],color='k')

   #make a filled black box from left edge to 1/4 way across
   fill([x1,x2,x2,x1,x1],[ytop,ytop,ybottom,ybottom,ytop],'k')
   #make a filled white box from 1/4 way across to 1/2 way across
   fill([x2,xc,xc,x2,x2],[ytop,ytop,ybottom,ybottom,ytop],'w')
   #make a filled white box from 1/2 way across to 3/4 way across
   fill([xc,x3,x3,xc,xc],[ytop,ytop,ybottom,ybottom,ytop],'k')
   #make a filled white box from 3/4 way across to end
   fill([x3,x4,x4,x3,x3],[ytop,ytop,ybottom,ybottom,ytop],'w')
  #plot 3 tick marks at left edge, center, and right edge
   m.plot([x1,x1],[ytick,ybottom],color='k')
   m.plot([xc,xc],[ytick,ybottom],color='k')
   m.plot([x4,x4],[ytick,ybottom],color='k')

   #label 3 tick marks
   text(x1,ytext,'%d' % (0),\
   horizontalalignment='center',\
   verticalalignment='top',\
   fontsize=9)
   text(xc,ytext,'%d' % (round((length/2)/1000)),\
   horizontalalignment='center',\
   verticalalignment='top',\
   fontsize=9)
   text(x4,ytext,'%d' % (round((length)/1000)),\
   horizontalalignment='center',\
   verticalalignment='top',\
   fontsize=9)

   #put units on top
   text(xc,ytop+yoffset/2,'km',\
   horizontalalignment='center',\
   verticalalignment='bottom',\
   fontsize=9)

# setup of basemap ('lcc' = lambert conformal conic).
# use major and minor sphere radii from WGS84 ellipsoid.
m = Basemap2 
(llcrnrlon=-145.5,llcrnrlat=1.,urcrnrlon=-2.566,urcrnrlat=46.352,\

 rsphere=(6378137.00,6356752.3142),\
 resolution='l',area_thresh=1000.,projection='lcc',\
 lat_1=50.,lon_0=-107.)
# draw coastlines and political boundaries.
m.drawcoastlines()
m.fillcontinents()
# draw parallels and meridians.
# label on left, right and bottom of map.
m.drawparallels(arange(0.,80,20.),labels=[1,1,0,1])
m.drawmeridians(arange(10.,360.,30.),labels=[1,1,0,1])
# draw a line from x1,y to x2,y and label it with distance in km.
length = 3000 #kilometers
x1,y1 = 0.25*m.xmax, 0.25*m.ymax
lon1,lat1 = m(x1,y1,inverse=True)
m.drawscale(lon1,lat1,length)
title('a fancy map scale')
show()




--
Michael Hearne
[EMAIL PROTECTED] mailto:[EMAIL PROTECTED]
(303) 273-8620
USGS National Earthquake Information Center
1711 Illinois St. Golden CO 80401
Senior Software Engineer
Synergetics, Inc.

Re: [Matplotlib-users] basemap scalebar

2008-03-03 Thread Michael Hearne
Jeff - That would replicate the simple scale-bar from GMT.  Below  
is my not-complete attempt at replicating the fancy scale bar.  It  
would need some options for specifying different units (miles,  
nautical miles, etc.) and perhaps some more attention to spacing of  
the text from the scale bar and tick marks...


--Mike

from numpy import *
from matplotlib.toolkits.basemap import Basemap, pyproj
from pylab import *
# add drawscale method to Basemap class.
class Basemap2(Basemap):
   def drawscale(self,lon,lat,length,yoffset=None):
   draw a fancy map scale from lon-length/2,lat-yoffset to
   lon-length/2,lat-yoffset, label it with actual distance in km
   length = length*1000 #input length is km

   #we need 5 sets of x coordinates (in map units)
   #center of scale
   xc,yc = self(lon,lat)
   #left edge of scale
   lon1,lat1 = self(xc-length/2,yc,inverse=True)
   x1,y1 = self(lon1,lat1)
   #quarter scale
   lon2,lat2 = self(xc-length/4,yc,inverse=True)
   x2,y2 = self(lon2,lat2)
   #three quarter scale
   lon3,lat3 = self(xc+length/4,yc,inverse=True)
   x3,y3 = self(lon3,lat3)
   #right edge of scale
   lon4,lat4 = self(xc+length/2,yc,inverse=True)
   x4,y4 = self(lon4,lat4)

   if yoffset is None: yoffset = 0.1*length

   #plot top line
   ytop = yc+yoffset/2
   ybottom = yc-yoffset/2
   ytick = ybottom - yoffset/2
   ytext = ytick - yoffset/2
   m.plot([x1,x4],[ytop,ytop],color='k')
   #plot bottom line
   m.plot([x1,x4],[ybottom,ybottom],color='k')
   #plot left edge
   m.plot([x1,x1],[ybottom,ytop],color='k')
   #plot right edge
   m.plot([x4,x4],[ybottom,ytop],color='k')

   #make a filled black box from left edge to 1/4 way across
   fill([x1,x2,x2,x1,x1],[ytop,ytop,ybottom,ybottom,ytop],'k')
   #make a filled white box from 1/4 way across to 1/2 way across
   fill([x2,xc,xc,x2,x2],[ytop,ytop,ybottom,ybottom,ytop],'w')
   #make a filled white box from 1/2 way across to 3/4 way across
   fill([xc,x3,x3,xc,xc],[ytop,ytop,ybottom,ybottom,ytop],'k')
   #make a filled white box from 3/4 way across to end
   fill([x3,x4,x4,x3,x3],[ytop,ytop,ybottom,ybottom,ytop],'w')

   #plot 3 tick marks at left edge, center, and right edge
   m.plot([x1,x1],[ytick,ybottom],color='k')
   m.plot([xc,xc],[ytick,ybottom],color='k')
   m.plot([x4,x4],[ytick,ybottom],color='k')

   #label 3 tick marks
   text(x1,ytext,'%d' % (0),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
   text(xc,ytext,'%d' % (round((length/2)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)
   text(x4,ytext,'%d' % (round((length)/1000)),\
horizontalalignment='center',\
verticalalignment='top',\
fontsize=9)

   #put units on top
   text(xc,ytop+yoffset/2,'km',\
horizontalalignment='center',\
verticalalignment='bottom',\
fontsize=9)

# setup of basemap ('lcc' = lambert conformal conic).
# use major and minor sphere radii from WGS84 ellipsoid.
m = Basemap2 
(llcrnrlon=-145.5,llcrnrlat=1.,urcrnrlon=-2.566,urcrnrlat=46.352,\

  rsphere=(6378137.00,6356752.3142),\
  resolution='l',area_thresh=1000.,projection='lcc',\
  lat_1=50.,lon_0=-107.)
# draw coastlines and political boundaries.
m.drawcoastlines()
m.fillcontinents()
# draw parallels and meridians.
# label on left, right and bottom of map.
m.drawparallels(arange(0.,80,20.),labels=[1,1,0,1])
m.drawmeridians(arange(10.,360.,30.),labels=[1,1,0,1])
# draw a line from x1,y to x2,y and label it with distance in km.
length = 3000 #kilometers
x1,y1 = 0.25*m.xmax, 0.25*m.ymax
lon1,lat1 = m(x1,y1,inverse=True)
m.drawscale(lon1,lat1,length)
title('a fancy map scale')
show()




--
Michael Hearne
[EMAIL PROTECTED]
(303) 273-8620
USGS National Earthquake Information Center
1711 Illinois St. Golden CO 80401
Senior Software Engineer
Synergetics, Inc.
--


-
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users