Make transparent ocean to allow image underlay in pyGMT

I’ve got a geotiff file that I’m plotting with pyGMT. I really need the ocean to be transparent AND I also need the 3d effect on land from shading. My goal is to create a shadow with PIL and overlay the map on that to get a 3D coastline effect (via the shadow). In order for that to work, the ocean should be transparent. using PIL to make a color translaprent results in some jagged edges and bleeding. While it’s possible that I can get it right manually, I really feel there should be a workaround in pyGMT.

I’ve been completely unable to get the ocean to be transparent in pyGMT. I’ve tried various solutions for over 8 hours today. At this point, I’d even setting for a land mask where the shadow is generated for a coastline only and I’d manually add it in photoshop. An automated solution would be ideal though! code below

Summary Requirements:

  1. Ocean = Transparent
  2. Land = 3d effect from shading/azimuth

Thanks!

# region_map is just a list of lats and longs for region.
# grid_map is an Xarray of a DEM geotiff file

lon_spacing = abs(float(grid_map.lon[1] - grid_map.lon[0]))
lat_spacing = abs(float(grid_map.lat[1] - grid_map.lat[0]))
spacing = f"{lon_spacing}/{lat_spacing}"
land_mask = pygmt.grdlandmask(
    region=region_map,
    spacing=spacing,
    maskvalues=[1, 0],   # land=1, ocean=0
)

fig = pygmt.Figure()
with pygmt.config(FONT=f"{FONT}"):
    fig.basemap(
        region=region_map,
        projection="M12c",
        frame=["af+s25p/25p/gray30", 'g']
    )

fig.grdimage(grid=grid_map, region=region_map, cmap='viridis', shading=intensity)

# Overlay land mask to clip the ocean
fig.grdimage(
    grid=land_mask,
    cmap="gray",         # color land (or choose something else)
    transparency=100     # ocean fully transparent
)

fig.show()

Please respect the posting tags. If your question is about PyGMT post under that category.

hey…this might be dumb, but I don’t think there’s a pyGMT tag. At least nothing shows up when I try to tag it was that. forums could use some fine tuning?

Sorry, it’s not a tag, it is a category. When one start a new topic we must choose a category.

Hi @tw21,

maybe grdclip could be helpful here. You can use it to set values below zero to NaN and then use Figure.grdimage with nan_transparent=True to plot NaN values transparent:

import pygmt

region = [-5, 12, 50, 60]

fig = pygmt.Figure()
fig.basemap(region=region, projection="M10c", frame=True)

# Image in the background
fig.image(
    imagefile="https://oceania.generic-mapping-tools.org/cache/needle.jpg",
    position="jMC+w10c",
)

# Set values below 0 to NaN
grid_clip = pygmt.grdclip("@earth_relief_03m", region=region, below=[0, "NaN"])
# Set up colormap
pygmt.makecpt(cmap="oleron", series=[0, 2000])
# Plot grid with color-coding with NaN being transparent
fig.grdimage(grid=grid_clip, cmap=True, shading=True, nan_transparent=True)
# Add colorbar
fig.colorbar(frame=True)

fig.show()