Re: [Matplotlib-users] basemap: Mask the ocean [SEC=UNCLASSIFIED]

2009-11-04 Thread Stephane Raynaud
Maybe using path clipping you can plot only over land like this :

--
import numpy as np
from mpl_toolkits.basemap import Basemap
import pylab as plt
import matplotlib.patches as patches
import matplotlib.transforms as transforms

ll_lat = -38.10  # extent of area of interest
ll_lon = 145.06
ur_lat = -38.00
ur_lon = 145.16

# create data points all on land
fudge = ((ll_lon+0.05,  ur_lat-0.00,   1000),
(ll_lon+0.05,  ur_lat-0.01,   2000),
(ll_lon+0.05,  ur_lat-0.02,   3000),
(ll_lon+0.05,  ur_lat-0.03,   4000),
(ll_lon+0.04,  ur_lat-0.025,  1000),
(ll_lon+0.043, ur_lat-0.036,  1),
(ll_lon+0.047, ur_lat-0.041,  2),
(ll_lon+0.07,  ur_lat-0.07,   4000),
(ll_lon+0.08,  ur_lat-0.08,   3000),
(ll_lon+0.09,  ur_lat-0.09,   2000),
(ll_lon+0.10,  ur_lat-0.10,   1000))

data = np.ones((3, len(fudge)))
for (i, (lon, lat, val)) in enumerate(fudge):
   data[0,i] = lon
   data[1,i] = lat
   data[2,i] = val

# plot the data
fig = plt.figure()
m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat,
  llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='f')

# +CHANGES
coll = plt.hexbin(data[0,:], data[1,:], data[2,:], gridsize=5)
ax = plt.gca()
for n, poly in enumerate(m.coastpolygons):
type = m.coastpolygontypes[n]
if type in [1,3]:
p = patches.Polygon(np.asarray(poly).T)
p.set_color('none')
ax.add_patch(p)
m.set_axes_limits(ax=ax)
coll.set_clip_path(p)
# -CHANGES

plt.show()
--

On Wed, Nov 4, 2009 at 1:17 AM, ross.wil...@ga.gov.au wrote:



 -Original Message-
 From: Jeff Whitaker [mailto:jsw...@fastmail.fm]
 Sent: Tuesday, 3 November 2009 02:53
 To: Stephane Raynaud
 Cc: Wilson Ross; matplotlib-users@lists.sourceforge.net
 Subject: Re: [Matplotlib-users] basemap: Mask the ocean [SEC=UNCLASSIFIED]

 Stephane Raynaud wrote:
  Ross,
 
 
  one way is to mask (or remove) ocean points using the _geoslib module
  provided with basemap.
  When you create a Basemap instance, you can retrieve all its polygons
  land (continents and islands) with mymap.coastpolygons.
  Thay are stored as numpy arrays, and you can convert them to
  _geoslib.Polygon objects :
 
  poly = _geoslib.Polygon(N.asarray(coastalpoly).T)
 
  Then you loop over all Polygons and all (x,y) points and test :
 
  good_point = _geoslib.Point((x,y)).within(poly)
 
  Thanks to this method, you can choose you optimal resolution.
  You can even compute the intersection of you hexagons with coastal
  polygons using .intersection() and .area (instead of simply checking
  if the center is inside) and then reject points depending the fraction
  of the cell covered by land (or ocean).

 Following Stephane's excellent suggestion, here's a prototype Basemap
 method that checks to see if a point is on land or over water.  Ross -
 if you find it useful I'll include it in the next release.  Note that it
 will be slow for lots of points or large map regions.

 -Jeff
 --

 Yes, Stephane's approach is nice and Jeff has nicely encapsulated the
 approach. I'll put that into my bag of tricks!

 However it doesn't quite do what I want.  My data does not have any points
 in the ocean; the hex binning creates hexagonal patches that extend out into
 the ocean. As a physicist I say that's a representation artifact and leave
 it at that, but my end-users want that 'bleed' into the ocean removed.  My
 argument that they are losing data falls on deaf ears.

 Here's an even more contrived example that improves on my poor previous
 attempt to explain the problem:
 
 import numpy as np
 import matplotlib.pyplot as plt
 from mpl_toolkits.basemap import Basemap

 ll_lat = -38.10  # extent of area of interest
 ll_lon = 145.06
 ur_lat = -38.00
 ur_lon = 145.16

 # create data points all on land
 fudge = ((ll_lon+0.05,  ur_lat-0.00,   1000),
 (ll_lon+0.05,  ur_lat-0.01,   2000),
 (ll_lon+0.05,  ur_lat-0.02,   3000),
 (ll_lon+0.05,  ur_lat-0.03,   4000),
 (ll_lon+0.04,  ur_lat-0.025,  1000),
 (ll_lon+0.043, ur_lat-0.036,  1),
 (ll_lon+0.047, ur_lat-0.041,  2),
 (ll_lon+0.07,  ur_lat-0.07,   4000),
 (ll_lon+0.08,  ur_lat-0.08,   3000),
 (ll_lon+0.09,  ur_lat-0.09,   2000),
 (ll_lon+0.10,  ur_lat-0.10,   1000))

 data = np.ones((3, len(fudge)))
 for (i, (lon, lat, val)) in enumerate(fudge):
data[0,i] = lon
data[1,i] = lat
data[2,i] = val

 # plot the data
 fig = plt.figure()
 m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat,
llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='f')
 plt.hexbin(data[0,:], data[1,:], data[2,:], gridsize=5)
 m.drawcoastlines(linewidth=0.5, color

Re: [Matplotlib-users] basemap: Mask the ocean [SEC=UNCLASSIFIED]

2009-11-03 Thread Ross.Wilson


-Original Message-
From: Jeff Whitaker [mailto:jsw...@fastmail.fm]
Sent: Tuesday, 3 November 2009 02:53
To: Stephane Raynaud
Cc: Wilson Ross; matplotlib-users@lists.sourceforge.net
Subject: Re: [Matplotlib-users] basemap: Mask the ocean [SEC=UNCLASSIFIED]

Stephane Raynaud wrote:
 Ross,


 one way is to mask (or remove) ocean points using the _geoslib module
 provided with basemap.
 When you create a Basemap instance, you can retrieve all its polygons
 land (continents and islands) with mymap.coastpolygons.
 Thay are stored as numpy arrays, and you can convert them to
 _geoslib.Polygon objects :

 poly = _geoslib.Polygon(N.asarray(coastalpoly).T)

 Then you loop over all Polygons and all (x,y) points and test :

 good_point = _geoslib.Point((x,y)).within(poly)

 Thanks to this method, you can choose you optimal resolution.
 You can even compute the intersection of you hexagons with coastal
 polygons using .intersection() and .area (instead of simply checking
 if the center is inside) and then reject points depending the fraction
 of the cell covered by land (or ocean).

Following Stephane's excellent suggestion, here's a prototype Basemap
method that checks to see if a point is on land or over water.  Ross -
if you find it useful I'll include it in the next release.  Note that it
will be slow for lots of points or large map regions.

-Jeff
--

Yes, Stephane's approach is nice and Jeff has nicely encapsulated the approach. 
I'll put that into my bag of tricks!

However it doesn't quite do what I want.  My data does not have any points in 
the ocean; the hex binning creates hexagonal patches that extend out into the 
ocean. As a physicist I say that's a representation artifact and leave it at 
that, but my end-users want that 'bleed' into the ocean removed.  My argument 
that they are losing data falls on deaf ears.

Here's an even more contrived example that improves on my poor previous attempt 
to explain the problem:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

ll_lat = -38.10  # extent of area of interest
ll_lon = 145.06
ur_lat = -38.00
ur_lon = 145.16

# create data points all on land
fudge = ((ll_lon+0.05,  ur_lat-0.00,   1000),
 (ll_lon+0.05,  ur_lat-0.01,   2000),
 (ll_lon+0.05,  ur_lat-0.02,   3000),
 (ll_lon+0.05,  ur_lat-0.03,   4000),
 (ll_lon+0.04,  ur_lat-0.025,  1000),
 (ll_lon+0.043, ur_lat-0.036,  1),
 (ll_lon+0.047, ur_lat-0.041,  2),
 (ll_lon+0.07,  ur_lat-0.07,   4000),
 (ll_lon+0.08,  ur_lat-0.08,   3000),
 (ll_lon+0.09,  ur_lat-0.09,   2000),
 (ll_lon+0.10,  ur_lat-0.10,   1000))

data = np.ones((3, len(fudge)))
for (i, (lon, lat, val)) in enumerate(fudge):
data[0,i] = lon
data[1,i] = lat
data[2,i] = val

# plot the data
fig = plt.figure()
m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat,
   llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='f')
plt.hexbin(data[0,:], data[1,:], data[2,:], gridsize=5)
m.drawcoastlines(linewidth=0.5, color='k')
plt.show()


None of the data points are on land, as can be seen if you change the 
'gridsize' parameter to 100 or so (land is to the NE).  However, when 
gridsize=5, the red hexagon in the middle extends out into the ocean.  My users 
want that hexagon and others like it clipped at the coastline.

Crazy people, users.

Ross

--
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] basemap: Mask the ocean [SEC=UNCLASSIFIED]

2009-11-02 Thread Stephane Raynaud
Ross,


one way is to mask (or remove) ocean points using the _geoslib module
provided with basemap.
When you create a Basemap instance, you can retrieve all its polygons land
(continents and islands) with mymap.coastpolygons.
Thay are stored as numpy arrays, and you can convert them to
_geoslib.Polygon objects :

poly = _geoslib.Polygon(N.asarray(coastalpoly).T)

Then you loop over all Polygons and all (x,y) points and test :

good_point = _geoslib.Point((x,y)).within(poly)

Thanks to this method, you can choose you optimal resolution.
You can even compute the intersection of you hexagons with coastal polygons
using .intersection() and .area (instead of simply checking if the center is
inside) and then reject points depending the fraction of the cell covered by
land (or ocean).

On Mon, Nov 2, 2009 at 8:07 AM, ross.wil...@ga.gov.au wrote:

 Listers,

 I'm using basemap to plot randomly sampled values (x,y,z) through hexbin.
  This produces a very nice result. Some sample code is:
 --
 import numpy as np
 from numpy.random import seed
 import matplotlib.pyplot as plt
 from mpl_toolkits.basemap import Basemap
 from matplotlib.mlab import griddata

 ll_lat = -38.39477  # extent of area of interest
 ll_lon = 144.54767
 ur_lat = -37.51642
 ur_lon = 145.67144

 num_points = 100# sample points

 # create random sampling over the area of interest
 seed(0)
 data = np.ones((3, num_points))
 data[0,:] *= ll_lon + np.random.random((num_points))*(ur_lon-ll_lon)
 data[1,:] *= ll_lat + np.random.random((num_points))*(ur_lat-ll_lat)
 data[2,:] *= np.random.random((num_points))*1

 # plot the data
 fig = plt.figure()
 ax = fig.add_subplot(111)
 m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat,
llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='f',
suppress_ticks=False, area_thresh=0.5)
 plt.hexbin(data[0,:], data[1,:], data[2,:], zorder=3)
 m.fillcontinents(color=(0.8,0.8,0.8,0), zorder=1)
 m.drawcoastlines(linewidth=0.25, color='k', zorder=2)
 plt.show()
 --

 This contrived example shows a sparse set of hexagons on both land and
 ocean.  I would like the hexagons over the ocean to be hidden.  I can make
 the ones on land disappear by changing the 'zorder' parameter of .hexbin()
 to 0.  However I have found no way of doing the inverse and hiding hexagons
 over the ocean.

 Using drawlsmask() is too crude at a 5-minute resolution.

 Any ideas?

 Thanks,
 Ross


 --
 Come build with us! The BlackBerry(R) Developer Conference in SF, CA
 is the only developer event you need to attend this year. Jumpstart your
 developing skills, take BlackBerry mobile applications to market and stay
 ahead of the curve. Join us from November 9 - 12, 2009. Register now!
 http://p.sf.net/sfu/devconference
 ___
 Matplotlib-users mailing list
 Matplotlib-users@lists.sourceforge.net
 https://lists.sourceforge.net/lists/listinfo/matplotlib-users




-- 
Stephane Raynaud
--
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] basemap: Mask the ocean [SEC=UNCLASSIFIED]

2009-11-02 Thread Jeff Whitaker

Stephane Raynaud wrote:

Ross,


one way is to mask (or remove) ocean points using the _geoslib module 
provided with basemap.
When you create a Basemap instance, you can retrieve all its polygons 
land (continents and islands) with mymap.coastpolygons.
Thay are stored as numpy arrays, and you can convert them to 
_geoslib.Polygon objects :


poly = _geoslib.Polygon(N.asarray(coastalpoly).T)

Then you loop over all Polygons and all (x,y) points and test :

good_point = _geoslib.Point((x,y)).within(poly)

Thanks to this method, you can choose you optimal resolution.
You can even compute the intersection of you hexagons with coastal 
polygons using .intersection() and .area (instead of simply checking 
if the center is inside) and then reject points depending the fraction 
of the cell covered by land (or ocean).


Following Stephane's excellent suggestion, here's a prototype Basemap 
method that checks to see if a point is on land or over water.  Ross - 
if you find it useful I'll include it in the next release.  Note that it 
will be slow for lots of points or large map regions.


-Jeff


On Mon, Nov 2, 2009 at 8:07 AM, ross.wil...@ga.gov.au 
mailto:ross.wil...@ga.gov.au wrote:


Listers,

I'm using basemap to plot randomly sampled values (x,y,z) through
hexbin.  This produces a very nice result. Some sample code is:
--
import numpy as np
from numpy.random import seed
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.mlab import griddata

ll_lat = -38.39477  # extent of area of interest
ll_lon = 144.54767
ur_lat = -37.51642
ur_lon = 145.67144

num_points = 100# sample points

# create random sampling over the area of interest
seed(0)
data = np.ones((3, num_points))
data[0,:] *= ll_lon + np.random.random((num_points))*(ur_lon-ll_lon)
data[1,:] *= ll_lat + np.random.random((num_points))*(ur_lat-ll_lat)
data[2,:] *= np.random.random((num_points))*1

# plot the data
fig = plt.figure()
ax = fig.add_subplot(111)
m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat,
   llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='f',
   suppress_ticks=False, area_thresh=0.5)
plt.hexbin(data[0,:], data[1,:], data[2,:], zorder=3)
m.fillcontinents(color=(0.8,0.8,0.8,0), zorder=1)
m.drawcoastlines(linewidth=0.25, color='k', zorder=2)
plt.show()
--

This contrived example shows a sparse set of hexagons on both land
and ocean.  I would like the hexagons over the ocean to be hidden.
 I can make the ones on land disappear by changing the 'zorder'
parameter of .hexbin() to 0.  However I have found no way of doing
the inverse and hiding hexagons over the ocean.

Using drawlsmask() is too crude at a 5-minute resolution.

Any ideas?

Thanks,
Ross


--
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year.
Jumpstart your
developing skills, take BlackBerry mobile applications to market
and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
mailto:Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users




--
Stephane Raynaud


--
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!

http://p.sf.net/sfu/devconference


___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
  



--
Jeffrey S. Whitaker Phone  : (303)497-6313
Meteorologist   FAX: (303)497-6449
NOAA/OAR/PSD  R/PSD1Email  : jeffrey.s.whita...@noaa.gov
325 BroadwayOffice : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web: http://tinyurl.com/5telg

import numpy as np
from numpy import ma
from numpy.random import seed
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap, _geoslib
from matplotlib.mlab import griddata

ll_lat = -38.39477  # extent of area of interest
ll_lon = 144.54767
ur_lat = -37.51642
ur_lon = 145.67144

num_points = 100# sample points

# create random 

[Matplotlib-users] basemap: Mask the ocean [SEC=UNCLASSIFIED]

2009-11-01 Thread Ross.Wilson
Listers,

I'm using basemap to plot randomly sampled values (x,y,z) through hexbin.  This 
produces a very nice result. Some sample code is:
--
import numpy as np
from numpy.random import seed
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.mlab import griddata

ll_lat = -38.39477  # extent of area of interest
ll_lon = 144.54767
ur_lat = -37.51642
ur_lon = 145.67144

num_points = 100# sample points

# create random sampling over the area of interest
seed(0)
data = np.ones((3, num_points))
data[0,:] *= ll_lon + np.random.random((num_points))*(ur_lon-ll_lon)
data[1,:] *= ll_lat + np.random.random((num_points))*(ur_lat-ll_lat)
data[2,:] *= np.random.random((num_points))*1

# plot the data
fig = plt.figure()
ax = fig.add_subplot(111)
m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat,
llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='f',
suppress_ticks=False, area_thresh=0.5)
plt.hexbin(data[0,:], data[1,:], data[2,:], zorder=3)
m.fillcontinents(color=(0.8,0.8,0.8,0), zorder=1)
m.drawcoastlines(linewidth=0.25, color='k', zorder=2)
plt.show()
--

This contrived example shows a sparse set of hexagons on both land and ocean.  
I would like the hexagons over the ocean to be hidden.  I can make the ones on 
land disappear by changing the 'zorder' parameter of .hexbin() to 0.  However I 
have found no way of doing the inverse and hiding hexagons over the ocean.

Using drawlsmask() is too crude at a 5-minute resolution.

Any ideas?

Thanks,
Ross

--
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users