Basemap: Coastlines intersecting with map boundary

Hi there,

in basemap coastlines are apparently (always?) drawn as closed polygons not exceeding the map boundary, i.e. when the coastline intersects with the map boundary the polygon is continued along the map boundary until the next intersection point. The somewhat annoying side effect of this is a map boundary that appears thicker where it crosses landmasses. See for instance on http://matplotlib.org/basemap/users/examples the example "Plot hurricane tracks from a shapefile" where clearly the upper and left map boundaries are thicker where they cross the western U.S. or northern Canada. Another example where this effect is particularly pronounced is the example "Draw great circle between NY and London" on the same page. The effect gets worse if running these examples without antialiasing. Apparently only the upper and left boundaries are affected, whereas the lower and right boundaries are plotted properly.

It looks to me as if this might simply be a bug due to the coastline not aligning perfectly with the map boundary, perhaps because of some roundoff error. Is there a way to avoid this? Wouldn't it be better to draw the coastlines not as closed polygons but as collections of line segments?

Cheers,
Joachim

Joachim: I've noticed this myself, but have not found any solution. I suppose I could add an option to treat coastlines as line segments, but then you would not be able to use the fillcontinents method. Here's what happens now when a Basemap instance is created:

1) the intersection between the coastline polygons and the map boundary is computed using the geos C library.
2) the coastline polygons are clipped at the map boundary
3) the coordinates of the coastline polygons are transformed to map projection coordinates

Then, when the drawcoastlines or fillcontinents methods are called only the polygons inside the map projection region are drawn. This saves *a lot* of time when you're using high-resolution coastlines in a small map region. There is a similar process for political boundaries, but since they are line segments you don't see the "thickening" around the map edges.

Maybe one solution would be to clip the polygons to a region slightly larger than the actual map projection region.

-Jeff

···

On 9/15/12 8:05 AM, Joachim Saul wrote:

Hi there,

in basemap coastlines are apparently (always?) drawn as closed polygons not exceeding the map boundary, i.e. when the coastline intersects with the map boundary the polygon is continued along the map boundary until the next intersection point. The somewhat annoying side effect of this is a map boundary that appears thicker where it crosses landmasses. See for instance on Plotting data on a map (Example Gallery) — Basemap Matplotlib Toolkit 1.2.1 documentation the example "Plot hurricane tracks from a shapefile" where clearly the upper and left map boundaries are thicker where they cross the western U.S. or northern Canada. Another example where this effect is particularly pronounced is the example "Draw great circle between NY and London" on the same page. The effect gets worse if running these examples without antialiasing. Apparently only the upper and left boundaries are affected, whereas the lower and right boundaries are plotted properly.

It looks to me as if this might simply be a bug due to the coastline not aligning perfectly with the map boundary, perhaps because of some roundoff error. Is there a way to avoid this? Wouldn't it be better to draw the coastlines not as closed polygons but as collections of line segments?

Cheers,
Joachim

Jeff, thanks for your feedback!

Jeff Whitaker [15.09.2012 17:25]:

Hi there,

in basemap coastlines are apparently (always?) drawn as closed polygons not exceeding the map boundary, i.e. when the coastline intersects with the map boundary the polygon is continued along the map boundary until the next intersection point. The somewhat annoying side effect of this is a map boundary that appears thicker where it crosses landmasses. See for instance on Plotting data on a map (Example Gallery) — Basemap Matplotlib Toolkit 1.2.1 documentation the example "Plot hurricane tracks from a shapefile" where clearly the upper and left map boundaries are thicker where they cross the western U.S. or northern Canada. Another example where this effect is particularly pronounced is the example "Draw great circle between NY and London" on the same page. The effect gets worse if running these examples without antialiasing. Apparently only the upper and left boundaries are affected, whereas the lower and right boundaries are plotted properly.

It looks to me as if this might simply be a bug due to the coastline not aligning perfectly with the map boundary, perhaps because of some roundoff error. Is there a way to avoid this? Wouldn't it be better to draw the coastlines not as closed polygons but as collections of line segments?

Cheers,
Joachim

Joachim: I've noticed this myself, but have not found any solution. I suppose I could add an option to treat coastlines as line segments, but then you would not be able to use the fillcontinents method.

On the other hand, computing the coastlines /either/ as segments /or/ closed polygons might be inexpensive enough to be done on the fly - i.e. segments in drawcoastlines() but closed polygons in fillcontinents(). A computational penalty comes into play only where both are called. But I think this would be acceptable.

Here's what happens now when a Basemap instance is created:

1) the intersection between the coastline polygons and the map boundary is computed using the geos C library.
2) the coastline polygons are clipped at the map boundary
3) the coordinates of the coastline polygons are transformed to map projection coordinates

Then, when the drawcoastlines or fillcontinents methods are called only the polygons inside the map projection region are drawn. This saves *a lot* of time when you're using high-resolution coastlines in a small map region. There is a similar process for political boundaries, but since they are line segments you don't see the "thickening" around the map edges.

Generally speaking this optimization stragegy is absolutely fine and works well - except for this nasty little line width artefact. :wink:

Maybe one solution would be to clip the polygons to a region slightly larger than the actual map projection region.

That should work but on the other hand it seems a little hackish and the resulting code could be harder to understand. Besides the suggestion given above I still have the feeling that part of the problem might be related to some roundoff issue - how else could the presence of thickened lines be (apparently) confined to only the upper and left border?

Cheers,
Joachim

···

On 9/15/12 8:05 AM, Joachim Saul wrote:

Jeff, thanks for your feedback!

A workaround for this (having drawcoastlines use line segments instead of polygons) is now part of this pull request:

Let's move discussion there..

-Jeff

···

On 9/17/12 5:09 AM, Joachim Saul wrote:

Jeff Whitaker [15.09.2012 17:25]:

On 9/15/12 8:05 AM, Joachim Saul wrote:

Hi there,

in basemap coastlines are apparently (always?) drawn as closed polygons not exceeding the map boundary, i.e. when the coastline intersects with the map boundary the polygon is continued along the map boundary until the next intersection point. The somewhat annoying side effect of this is a map boundary that appears thicker where it crosses landmasses. See for instance on Plotting data on a map (Example Gallery) — Basemap Matplotlib Toolkit 1.2.1 documentation the example "Plot hurricane tracks from a shapefile" where clearly the upper and left map boundaries are thicker where they cross the western U.S. or northern Canada. Another example where this effect is particularly pronounced is the example "Draw great circle between NY and London" on the same page. The effect gets worse if running these examples without antialiasing. Apparently only the upper and left boundaries are affected, whereas the lower and right boundaries are plotted properly.

It looks to me as if this might simply be a bug due to the coastline not aligning perfectly with the map boundary, perhaps because of some roundoff error. Is there a way to avoid this? Wouldn't it be better to draw the coastlines not as closed polygons but as collections of line segments?

Cheers,
Joachim

Joachim: I've noticed this myself, but have not found any solution. I suppose I could add an option to treat coastlines as line segments, but then you would not be able to use the fillcontinents method.

On the other hand, computing the coastlines /either/ as segments /or/
closed polygons might be inexpensive enough to be done on the fly - i.e.
segments in drawcoastlines() but closed polygons in fillcontinents(). A
computational penalty comes into play only where both are called. But I
think this would be acceptable.

  Here's what happens now when a Basemap instance is created:

1) the intersection between the coastline polygons and the map boundary is computed using the geos C library.
2) the coastline polygons are clipped at the map boundary
3) the coordinates of the coastline polygons are transformed to map projection coordinates

Then, when the drawcoastlines or fillcontinents methods are called only the polygons inside the map projection region are drawn. This saves *a lot* of time when you're using high-resolution coastlines in a small map region. There is a similar process for political boundaries, but since they are line segments you don't see the "thickening" around the map edges.

Generally speaking this optimization stragegy is absolutely fine and
works well - except for this nasty little line width artefact. :wink:

Maybe one solution would be to clip the polygons to a region slightly larger than the actual map projection region.

That should work but on the other hand it seems a little hackish and the
resulting code could be harder to understand. Besides the suggestion
given above I still have the feeling that part of the problem might be
related to some roundoff issue - how else could the presence of
thickened lines be (apparently) confined to only the upper and left border?

Cheers,
Joachim

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
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