[Basemap] contour plot just inside country

hi, is it possible to restrict a contour plot to a
country? if i grid my data to projection coordinates
and then make a contour plot i can draw the country
borders on top, but since the data plotted outside
the country is a gridding artifact i would rather
not plot it.

to make it more clear what i mean:
http://rokuko.net/basicmap.png

any ideas? can one make a single country transparent?

best regards, yoshi

hi, is it possible to restrict a contour plot to a
country? if i grid my data to projection coordinates
and then make a contour plot i can draw the country
borders on top, but since the data plotted outside
the country is a gridding artifact i would rather
not plot it.

Yoshi: There is no mechanism for doing this. It is possible, but you would need a way to create a mask for all the grid points outside the country of interest, and then use this mask to create a masked array to pass to contourf.

-Jeff

···

On 7/14/11 2:25 PM, Yoshi Rokuko wrote:

to make it more clear what i mean:
http://rokuko.net/basicmap.png

any ideas? can one make a single country transparent?

best regards, yoshi

------------------------------------------------------------------------------
AppSumo Presents a FREE Video for the SourceForge Community by Eric
Ries, the creator of the Lean Startup Methodology on "Lean Startup
Secrets Revealed." This video shows you how to validate your ideas,
optimize your ideas and identify your business strategy.
http://p.sf.net/sfu/appsumosfdev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

+--------------------------------------------- Jeff Whitaker -----------+

···

On 7/14/11 2:25 PM, Yoshi Rokuko wrote:
> hi, is it possible to restrict a contour plot to a
> country? if i grid my data to projection coordinates
> and then make a contour plot i can draw the country
> borders on top, but since the data plotted outside
> the country is a gridding artifact i would rather
> not plot it.

Yoshi: There is no mechanism for doing this. It is possible, but you
would need a way to create a mask for all the grid points outside the
country of interest, and then use this mask to create a masked array to
pass to contourf.

-Jeff

wouldn't it be possible to create such a mask using internals from
Basemap.drawcountries() somehow?

best regards, yoshi

Jeff, I just had a thought…

Isn’t the country borders drawn as Path or Polygon objects? I believe there are some matplotlib internal functions that can be given a list of points (such as those for a grid) and a path and it will return which points are within the path and which are outside. One could use that to make the mask.

Might make for a nice feature for basemap in the upcoming v1.1.0 release.

Ben Root

···

On Fri, Jul 15, 2011 at 1:44 PM, Yoshi Rokuko <yoshi@…3676…> wrote:

±-------------------------------------------- Jeff Whitaker -----------+

On 7/14/11 2:25 PM, Yoshi Rokuko wrote:

hi, is it possible to restrict a contour plot to a

country? if i grid my data to projection coordinates

and then make a contour plot i can draw the country

borders on top, but since the data plotted outside

the country is a gridding artifact i would rather

not plot it.

Yoshi: There is no mechanism for doing this. It is possible, but you

would need a way to create a mask for all the grid points outside the

country of interest, and then use this mask to create a masked array to

pass to contourf.

-Jeff

wouldn’t it be possible to create such a mask using internals from

Basemap.drawcountries() somehow?

best regards, yoshi

` Ben/Yoshi: The countries are not polygons, they are line
segments. Worse yet, they are all just lumped together with no
metadata (no way to know which lines define the country you want).
If you had a shapefile with just the country of interest in it,
defined as a polygon, then it’s doable You could take a look at
the source code for the is_land method, which tests to see if a
given x,y point is inside any of the continent polygons.

  Let us know if you have you have the country polygon, and then I

can help you with the details.

  -Jeff

`
···
-- Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : 325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web :

Jeffrey.S.Whitaker@…259…http://tinyurl.com/5telg

sendJKki52 (1.24 KB)

germany.zip (8.8 KB)

Yoshi:
Here’s the basic idea:

  1. read the germany.dat file, use it to create a _geoslib Poly
    instance, i.e.
    from mpl_toolkits.basemap import _geoslib
    b = np.asarray([lons,lats]).T # lons and lats are lists.
    germanypoly = _geoslib.Polygon(b)
  2. loop over all the points on the grid and do
    inside = _geoslib.Point((lonpt,latpt)).within(germanypoly)
    filling a boolean array with the values.
  3. use this boolean array as a mask to create a masked array from
    your data. Then, when you plot the masked array with contourf only
    the points inside germany will be contoured.
    Give this a try and let us know how it goes.
    -Jeff
···
+----------------------------------------- Jeff Whitaker -----------+

Jeff, I just had a thought....
Isn't the country borders drawn as Path or Polygon objects? I believe there are some matplotlib internal functions that can be given a list of points (such as those for a grid) and a path and it will return which points are within the path and which are outside. One could use that to make the mask.
Might make for a nice feature for basemap in the upcoming v1.1.0 release.
Ben Root

Ben/Yoshi: The countries are not polygons, they are line segments. Worse yet, they are all just lumped together with no metadata (no way to know which lines define the country you want). If you had a shapefile with just the country of interest in it, defined as a polygon, then it's doable You could take a look at the source code for the is_land method, which tests to see if a given x,y point is inside any of the continent polygons.
Let us know if you have you have the country polygon, and then I can help you with the details.
-Jeff

>>> Sorry for being late, i was really busy. Thank you for your offer, I have
>>> the polygon now (attached), could you help me with this?
>>> Best regards, Yoshi

+----------------------------------------- Jeff Whitaker -----------+

Here's the basic idea:

1) read the germany.dat file, use it to create a _geoslib Poly instance,
i.e.

from mpl_toolkits.basemap import _geoslib
b = np.asarray([lons,lats]).T # lons and lats are lists.
germanypoly = _geoslib.Polygon(b)

2) loop over all the points on the grid and do

inside = _geoslib.Point((lonpt,latpt)).within(germanypoly)

filling a boolean array with the values.

3) use this boolean array as a mask to create a masked array from your
data. Then, when you plot the masked array with contourf only the
points inside germany will be contoured.

Give this a try and let us know how it goes.

-Jeff

because of islands it doesn't work as expected i guess?

here is what i did:

bmap = Basemap(projection='aeqd', ...)
x, y = bmap(lons, lats)
npoints = 300
xi = np.linspace(np.amin(x), np.amax(x), npoints*.7178)
yi = np.linspace(np.amin(y), np.amax(y), npoints)
zi = griddata(x, y, var, xi, yi)
inside = np.zeros_like(zi)
lon, lat = np.loadtxt('germany-lon-lat-np.arr')
bx, by = bmap(lon, lat)
b = np.asarray([bx, by]).T
poly = _geoslib.Polygon(b)
i = 0
# i know this is slow, but ...
for y in yi:
    for x in xi:
        inside.flat[i] = _geoslib.Point((x,y)).within(poly)
        i += 1
mzi = ma.masked_array(zi, mask=inside)

here is what it looks like:
http://rokuko.net/test.png

matlab includes NaNs right before and after islands in the lon
lat lists, is there something similar ?

thank you so far, best regards

PS
http://rokuko.net/germany-lon-lat-np.arr

Yoshi: Islands would be a problem. I was assuming you had one polygon. Can you get rid of the islands so you just have one closed polygon to use for a mask?

-Jeff

···

On 7/23/11 9:32 AM, Yoshi Rokuko wrote:

+----------------------------------------- Jeff Whitaker -----------+

Here's the basic idea:

1) read the germany.dat file, use it to create a _geoslib Poly instance,
i.e.

from mpl_toolkits.basemap import _geoslib
b = np.asarray([lons,lats]).T # lons and lats are lists.
germanypoly = _geoslib.Polygon(b)

2) loop over all the points on the grid and do

inside = _geoslib.Point((lonpt,latpt)).within(germanypoly)

filling a boolean array with the values.

3) use this boolean array as a mask to create a masked array from your
data. Then, when you plot the masked array with contourf only the
points inside germany will be contoured.

Give this a try and let us know how it goes.

-Jeff

because of islands it doesn't work as expected i guess?

here is what i did:

bmap = Basemap(projection='aeqd', ...)
x, y = bmap(lons, lats)
npoints = 300
xi = np.linspace(np.amin(x), np.amax(x), npoints*.7178)
yi = np.linspace(np.amin(y), np.amax(y), npoints)
zi = griddata(x, y, var, xi, yi)
inside = np.zeros_like(zi)
lon, lat = np.loadtxt('germany-lon-lat-np.arr')
bx, by = bmap(lon, lat)
b = np.asarray([bx, by]).T
poly = _geoslib.Polygon(b)
i = 0
# i know this is slow, but ...
for y in yi:
     for x in xi:
         inside.flat[i] = _geoslib.Point((x,y)).within(poly)
         i += 1
mzi = ma.masked_array(zi, mask=inside)

here is what it looks like:
http://rokuko.net/test.png

matlab includes NaNs right before and after islands in the lon
lat lists, is there something similar ?