How to plot a binary mask (xarray.Dataset) using pygmt.grdimage (1: Color and 0: Transparent)"

Hello, PyGMT community. How can I use pygmt.grdimage to plot only the ‘ones’ from an xarray dataset with a specific color (e.g., green) while making the ‘zeros’ areas transparent? I’ve already tried setting the zeros as np.NaN and using nan_transparent=True, as well as experimenting with bit_color=‘green+f’, but the desired effect isn’t being achieved. Could someone provide guidance on how to modify my code to achieve this visualization?

import numpy as np
import xarray as xr
import pygmt

# Create a random 100x100 array with 0s and 1s
random_data = np.random.randint(2, size=(100, 100))

# Create an xarray dataset from the random array
dims = ('x', 'y')
coords = {'x': np.arange(100), 'y': np.arange(100)}
data_array = xr.DataArray(random_data, dims=dims, coords=coords)
dataset = xr.Dataset({'data': data_array})

fig = pygmt.Figure()
fig.grdimage(grid=dataset.data, projection='X20c')
fig.show()

Thank you in advance,
Robson

Hello @Robson,

By default nan_transparent applies to grid nodes which are NaN. If you want another value to be transparent you have to append +z and state the desired value, e.g., nan_transparent="+z0".

Based on the documentation at https://www.pygmt.org/latest/api/generated/pygmt.Figure.grdimage.html bit_color seems to be available for 1-bit images only.

Maybe you can set up a colormap with the two desired colors for the values 0 and 1:

pygmt.makecpt(
    series=[0, 2, 1],
    cmap="black,green",
)

And later set the value 0 to transparent via nan_transparent.
The complete code would look like:

import numpy as np
import xarray as xr
import pygmt

# Create a random 100x100 array with 0s and 1s
np.random.seed(100)  # To have always the same random numbers
random_data = np.random.randint(2, size=(100, 100))

# Create an xarray dataset from the random array
dims = ('x', 'y')
coords = {'x': np.arange(100), 'y': np.arange(100)}
data_array = xr.DataArray(random_data, dims=dims, coords=coords)
dataset = xr.Dataset({'data': data_array})

fig = pygmt.Figure()

# Set up colormap with two desired colors for the values 0 and 1
pygmt.makecpt(
    series=[0, 2, 1],
    cmap="black,green",
)
fig.grdimage(
    grid=dataset.data,
    projection='X20c',
    nan_transparent="+z0",  # Make grid nodes which are zero transparent
    cmap=True,
)
fig.show()#method="external")
# fig.savefig(fname="grdimage_transparent_zero.png")

Output figure:

1 Like

Thanks for the solution. But I met the following errors when I tried your code ‘nan_transparent’.
It seems the -Q+z0 did not work. If I delete it, the code runs well.
Would you mind helping me this issue?

-----------Error

grdimage [ERROR]: Option -Q parsing failure.  Correct syntax:

-Q<color>
Specify <color> as one of:
• <gray> or <red>/<green>/<blue>, all in range 0-255;
• <cyan>/<magenta>/<yellow>/<black> in range 0-100%;
• <hue>-<saturation>-<value> in ranges 0-360, 0-1, 0-1;
• Any valid color name.
For PDF fill transparency, append @<transparency> in the range 0-100% [0 = opaque].
---------------------------------------------------------------------------
GMTCLibError                              Traceback (most recent call last)
Cell In[18], line 22
     17 # Set up colormap with two desired colors for the values 0 and 1
     18 pygmt.makecpt(
     19     series=[0, 2, 1],
     20     cmap="black,green",
     21 )
---> 22 fig.grdimage(
     23     grid=dataset.data,
     24     projection='X20c',
     25     nan_transparent="+z0",  # Make grid nodes which are zero transparent
     26     cmap=True,
     27 )
     28 fig.show()

File e:\miniconda3\lib\site-packages\pygmt\helpers\decorators.py:594, in use_alias..alias_decorator..new_module(*args, **kwargs)
    587     msg = (
    588         "Parameters 'Y' and 'yshift' are deprecated since v0.8.0. "
    589         "and will be removed in v0.12.0. "
    590         "Use Figure.shift_origin(yshift=...) instead."
    591     )
    592     warnings.warn(msg, category=SyntaxWarning, stacklevel=2)
--> 594 return module_func(*args, **kwargs)
...
    511         f"Module '{module}' failed with status code {status}:\n{self._error_message}"
    512     )

GMTCLibError: Module 'grdimage' failed with status code 72:
grdimage [ERROR]: Option -Q parsing failure.  Correct syntax:

EDIT: please format your post.

Hello @phalucy,

Welcome to the GMT forum :slightly_smiling_face:!

Can you please state your GMT and PyGMT versions?
The option +zvalue for -Q of grdimage was added in GMT 6.4, please see the changelog at https://docs.generic-mapping-tools.org/latest/changes.html#enhancements-in-gmt-6-4 (the fourth bullet point). Maybe you are using PyGMT with GMT 6.3 or older? Then you may want to update to GMT 6.4 and test if the code works afterward.

That exactly is my problem! I was using 6.3 instead of 6.4.
Thank you for reminding me that!
Now, the function works fine!