regionmask / regionmask

create masks of geospatial regions for arbitrary grids

Home Page:https://regionmask.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Smooth out edges with coarse data?

guidocioni opened this issue · comments

This may be kind of a long shot but still worth asking, so here we go...

I'm using regionmask to mask an xarray.Dataset containing geospatial data outside of a certain country border.
The problem that I have right now is that the "coarse" (~2km) resolution of the longitude and latitude arrays makes some edge artifacts quite visible when zooming in (see image).

203011256-2d94befe-ec5b-4176-87d2-6ffe75755d08

I'm using the shapefile drawn as black line in the picture to make the mask used then on the xarray dataset.

I cannot increase the resolution of the original dataset because this is the target grid that I'm interpolating too, but still I would be happy to mask the values outside of the country borders without having these artifacts on some regions.
Is there any way to do that?

Thanks

Do you think that is a plotting problem or a selection (i.e. regionmask) problem?

  • Do you have a regular lat/ lon grid or another projection?

  • Can you try plotting it with pcolormesh - in newer matplotlib and cartopy version that makes sure you grid cell boundaries are taken into account (only for testing purposes - so you can better see what is actually happening).

  • You cou try to add the grid cell centers as well (LON, LAT = np.meshgrid(ds.lon, ds.lat); ax.plot(LON.flatten(), LAT.flatten(), "o", color="r")` to understand what's going on.

  • If it's a regular grid you could include all edge gridpoints: #225 (comment)

  • You could also get a fractional overlap as shown in #38 (comment)

(both things I want to implement but have not gotten around to)

Do you think that is a plotting problem or a selection (i.e. regionmask) problem?

It is not a plotting problem: the data really looks like this. The problem is to find the best way to mask that region in a "smooth" way

  • Do you have a regular lat/ lon grid or another projection?

Regular

  • Can you try plotting it with pcolormesh - in newer matplotlib and cartopy version that makes sure you grid cell boundaries are taken into account (only for testing purposes - so you can better see what is actually happening).
  • You cou try to add the grid cell centers as well (LON, LAT = np.meshgrid(ds.lon, ds.lat); ax.plot(LON.flatten(), LAT.flatten(), "o", color="r")` to understand what's going on.

Here is the plot with pcolormesh and the grid points

87c2ac01-46d3-4182-b408-e0a90fac2b62

and here is the one with contourf and the grid points

61791f41-f396-48a6-9bbf-331490236514

I think the fact is that maskregion takes a "conservative" approach and only keeps the grid cells that are entirely inside the polygon defined by the shapefile.

Cannot seem to find that option as being valid for regionmask.Regions([polygon]).mask_3D

Hard to tell from that issue...what would this modification add to the current behaviour?

Thinking about this again, I'm pretty sure there is no way to smooth out the masking besides acting directly on the figure: as the mask will always be defined in terms of the original lat/lon coordinates it will always be "coarse". Still, it would be good to increase the area to also include edges into the mask.

Ok, I understood how to use the all_touched option. In order to have the same result as mask_3D I have done this

# Old method 
# mask = regionmask.Regions([polygon]).mask_3D(lon, lat).squeeze()
# New method
mask = regionmask.core.mask._mask_rasterize(
    lon, lat, region.polygons, region.numbers, all_touched=True)
# It is just a numpy array with 0 and NaNs so we convert to Boolean
mask = (mask  == 0)

It is indeed an improvement but I'm still missing some points :(
5b6d4cf0-b97d-4cc8-b0f9-769b7b1769bd

Yes, you could now plot your ocean and other countries over the mask. So it looks smooth.

However, it seems to me that you don't plot the shapefile that you use to create the mask. Can you confirm? There are many points (i.e. the center) that are inside the black polygon and not green. E.g. in the topmost row the first point that is gray (in your first figure in #407 (comment)).

Yes, you could now plot your ocean and other countries over the mask. So it looks smooth.

I'm already doing this for the oceans but for the countries it is a little bit more complicated because I have to select all but the one that I'm not masking and it's not super easy to do, at least in basemap.

However, it seems to me that you don't plot the shapefile that you use to create the mask. Can you confirm? There are many points (i.e. the center) that are inside the black polygon and not green. E.g. in the topmost row the first point that is gray (in your first figure in #407 (comment)).

You're right, I was using a different shapefile. I increased the shapefile resolution and now it's even better. Honestly, I think I'll settle with this result because improving even further it's probably to complicated, and not worth the final result.

Thanks for the help anyway!

You're welcome - thanks for using regionmask!