Thematic mapping of land cover by pygmt

See this PR on GitHub. I need to be told how we can separate a grayscale byte image from one that has category indices but no colormap (so a CPT is needed). Is there a rule that says those categories go from 1-n and what about 0?

Or do I just create a gray ramp 0-255 in the case of no image colormap and no -C? That would give teh blackish image shown earlier but presumably it will work well if truly a gray image.

The image has values 0-8 for a total of 9, but CPT has 8.

from gdalinfo LC2013.tif -mm:

Band 1 Block=4530x1 Type=Byte, ColorInterp=Gray
    Computed Min/Max=1.000,8.000
  NoData Value=0

so values are 1-8 (that is 8 categories), while zero is NAN (NoData can be absent or be some different value). The -mm stats indicates there is no NANs on that raster.

is it possible (and does it make sense) to enable grdimage producing the same result as:

gdal_translate -of netCDF LC2013.tif LC2013.nc
gmt grdimage LC2013.nc -png quick

those willing to plot in grayscale could use -Cgray or generate their own palette based on it? Or use -Cgray as a default palette for 1-byte 1-band rasters, stretching across the actual range?

Hello @weiji14
I mainly work on remote sensing image processing. This data is a land use map obtained through remote sensing image classification, where 1 to 8 represent different land cover types, such as water bodies and vegetation. The general display mode is 8-bit, which means pixel values range from 0 to 255. However, my data has pixel values ranging from 1 to 8, which are relatively small, resulting in darker colors when displayed. With our professional remote sensing software, it is easy to display different colors for different pixel values. Here, I would like to achieve this using pygmt because I find its output more visually appealing. However, I have noticed that pygmt has some minor drawbacks when creating land use thematic maps, such as the style of the scale bar being too simple.

No, that is incorrect. Values range from 0 to 8, so you have 9 classes and 8 colors.

julia> info(I)
A GMTimage object with 1 bands of type UInt8
Pixel node registration used
x_min: 99.41247324      x_max :101.076661152    x_inc :0.0003673704000000006    n_columns :4530
y_min: 38.340608528     y_max :40.00479644      y_inc :0.0003673704000000006    n_rows :4530
z_min: 0.0      z_max :8.0
Mem layout:     BRPa
PROJ: +proj=longlat +datum=WGS84 +no_defs
4530×4530 Matrix{UInt8}:
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  …  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7     4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4
 0  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7     4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4
 0  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7     4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4
 0  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7     4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4
 0  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  …  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4
 0  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7     4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4

Does this mean that Julia and gmt simply ignore that 0 is NAN in the .tif datafile? gdalinfo reports NoData Value=0, Python/rioxarray provides an indication: _FillValue: 0.

gdal_translate LC2013.tif LC2013.nc
gmt grdimage LC2013.nc -png quick -R99.4/99.45/38.34/38.35 -B

the result, a NAN color is assigned and used:

gdal_translate -ot Uint16 LC2013.tif LC2013-uint16.tif
gmt grdimage LC2013-uint16.tif -png quick -R99.4/99.45/38.34/38.35 -B

result, presence of NAN (NoData Value=0) seems ignored, zeroes are part of the color scale:

also, the color bar seems to include different data ranges (out of 1-8) when plotting .nc and .tif.

We should be able to detect if the TIF says NoData = 0 and assign it to NaN. But we gotta eat first.

Hello @Joaquim
This is the result opened with professional remote sensing image processing software, which counts the quantity of each pixel value, with no value of 0.

Tons of zeros there but flagged as NoValue so it does not count them, but of course they are there (a byte is a byte). We are working on flagging them as well.

To be honest, it’s the first time I see any use for a novalue in an image. Always thought that transparency was the solution for those pixels.

User could choose to add a NaN category in the CPT which will be plotted in the bar

0   white   ;No data
1   250/227/156   ;Cropland
...

Otherwise, if starts at 1 then we do not plot NaNs (0) in bar. However, I agree it then ought to be transparent.

Hello @Joaquim
You are correct, I don’t know why, but my data is supposed to have no 0 values, and I opened the data with gdal and found that the first row and column became 0 values.

I think we understand them now (the 0’s). They are flagged as the nodata value and hence should be ignored. That is what your commercial software does and we too in the GMTdev version. The fact that they are on the image’s edges indicate that they result from edge effects of the classification algorithm. I happen to be working on introducing classifications algorithms in GMT.jl/RemoteS.jl so I’m a bit curious on this. Did you calculate that classes image or downloaded from somewhere? If first, which algorithm was used?

Hello @Joaquim
I was downloading someone else’s publicly available dataset and cropping out my own research area.