## How can I plot overlay black land?

### Michael (view profile)

on 11 Aug 2014

on 5 Dec 2014

At the moment I have a plot that looks like the attached, with zero values being land.

How can I make the land black in this plot? without affecting the zero values in the data..

thanks, Michael

Michael

### Michael (view profile)

on 11 Aug 2014

the data is on a 1682 x 3600 grid...

## Products

### Kelly Kearney (view profile)

on 11 Aug 2014
Edited by Kelly Kearney

### Kelly Kearney (view profile)

on 11 Aug 2014

Plot using pcolor (not image or similar), mask out the land with NaNs, and set the axis color to black.

If you don't have a specific land mask already defined, you can use inpolygon with a coastline dataset. For example

```lat = linspace(-90, 90, 100);
lon = linspace(-180, 180, 100);
z = peaks(100);
```
```[long, latg] = meshgrid(lon, lat);
```
```C = load('coast');
island = inpolygon(long, latg, C.long, C.lat);
```
```z(island) = NaN;
pcolor(long, latg, z);
set(gca, 'color', 'k');
```

The inpolygon call will be a bit slow with a matrix your size, but you should only have to call that once and then can save the mask for later use. I use my inpolygons function instead, and it tends to be faster for tasks like this.

Image Analyst

### Image Analyst (view profile)

on 12 Aug 2014

Michael said "values in the data are also black" so no amount of plotting options and trickery will solve that. As I said in my comment, Michael, you have to change your data so that there are no "land" pixels in what is supposed to be the "water region". As long as they have the same intensity value, they will be there (unless you shrink the image so much they don't show up) and no amount of plotting gymnastics and chicanery will change that.

Kelly Kearney

### Kelly Kearney (view profile)

on 12 Aug 2014

Using the method I showed above, where land values are designated as such based on coastline polygons, it shouldn't matter. I assume he means that the land values are given a default value if 0, which also happens to be a perfectly valid data values. Therefore assigning the color black to 0 is not a good solution. Calculating the real land mask (based on polygons, not data == 0) will solve the problem.

Michael, did you try the inpolygons function I linked to? It's still slow, but not as slow as inoolygon. Of course, if you already have a land mask associated with the data, of course use that.

Excuse the typos, typing on a phone and it doesn't play well with this forum at all.

Kelly Kearney

### Kelly Kearney (view profile)

on 12 Aug 2014

Alternatively, assuming you're not planning to zoom in to full resolution with this figure, there's really no reason that your land mask has to be calculated at such a high resolution.

The following example calculates the land mask at 1/4 the resolution, then upsamples it for use as a mask. Only takes a ~30 sec on my computer.

Note that I had to add in the flatearthpoly call to close off Antarctica properly. I'm assuming you have the Mapping Toolbox, since you didn't comment on my use of the coast.mat dataset.

```nlat = 1682;
nlon = 3600;
```
```lat = linspace(-90, 90, nlat);
lon = linspace(-180, 180, nlon);
z = peaks(max(nlat,nlon));
z = z(1:nlat, 1:nlon);
```
```[long, latg] = meshgrid(lon, lat);
```
```C = load('coast');
[latc, lonc] = flatearthpoly(C.lat, C.long);
```
```lat2 = linspace(-90,90,nlat/4);
lon2 = linspace(-180,180,nlon/4);
[long2, latg2] = meshgrid(lon2, lat2);
```
```island = inpolygons(long2, latg2, lonc, latc);
island = interp2(long2, latg2, island, long, latg, 'nearest');
```
```z(island) = NaN;
pcolor(long, latg, z);
set(gca, 'color', 'k');
hold on;
plot(lonc, latc, 'w');
colorbar;
```

### Joseph Cheng (view profile)

on 11 Aug 2014

You can change the colormap used to display the image. First obtain the colormap used by:

` map = colormap;`

then change the color map corresponding to zero to black [0 0 0]

` map(1,:) = 0;`

then apply the colormap:

` colormap(map);`

Joseph Cheng

### Joseph Cheng (view profile)

on 11 Aug 2014

If that is a case you may want to check the imoverlay() function at the file exchange. using that function you would need to create a binary mask of the land values and then apply it using the imoverlay() function. I'm not sure what this will do to the color bar though.

Michael

### Michael (view profile)

on 11 Aug 2014

I tried this function but I cannot seem to get it to work...

I am using imagesc and this example seems to be for the imshow command.

Joseph Cheng

### Joseph Cheng (view profile)

on 11 Aug 2014

well you could do something like this.

```%create dummy image
images = 0:.01:1;
images=repmat(images,101,1);
```
```%create mask in the center.
%create a foreground flat image offset it to a value not used by the image
```
```f1 = figure;
h1= imagesc(images), colorbar;
```
```%generate the colormap
map = colormap;
%append black to the end of the colormap
map = colormap([map;gray(1)]);
```
```hold on;
%overlay the earth image with the foreground mask
%using the logic mask set the foreground to be transparent.
```
```%edit the colorbar to only show values for the earth image.
cbar_handle = findobj(f1,'tag','Colorbar')
pause(.1)
set(cbar_handle,'Ylim',[0 1])
```

the only problem i have with this right now is that the last line needs to have a pause of some value for it to work in a script. so here i have created a mask for the value of .5. in your case i'd create a mask of the land values of zero where i know i'll only have zero values for land then use that for the other data sets where there are zero values in the sea.

### Image Analyst (view profile)

on 11 Aug 2014

If you don't like the black line in the colorbar, you can convert to rgb, like this untested code:

```% Create standard colormap
customColorMap = jet(256);
% Make bottom color be black
customColorMap(1,:) = [0,0,0];
% Convert to RGB
rgbImage = ind2rgb(indexedImage, customColorMap);
% Display
imshow(rgbImage);
% Show color map, standard one, not custom one
colormap(jet(256));
colorbar;
```

Michael

### Michael (view profile)

on 11 Aug 2014

thanks, although I have to make it so that just the land is black, at the moment values in the data are also black.

Image Analyst

### Image Analyst (view profile)

on 11 Aug 2014

You must have some pixels in the water that are the same intensity as the land. How do you know they are not land? Maybe they are islands? If you want to filter out small specks that you don't want to be black, then use bwareaopen.

I'm going to be traveling for the next week after tomorrow, and not online very much, so if you can upload your indexed image (not the color one that you uploaded already), and point out what areas you don't want black, then I'll see if I can get time to look at it.

Image Analyst

on 22 Aug 2014

### corry (view profile)

on 21 Aug 2014

if your data is Z(i,j), where i=1682 and j=3600 then you must have land masking data (contain of 0 and 1), e.g. if land then the value is one and if ocean then the value is zero. Then do this calculation:

```for i=1:1682;
for j=1:3600;
if (land(i,j)==1);
Z(i,j) = NaN;
else;
Z(i,j) = Z(i,j);
end;
end;
end;
end;
```
```pcolor (Z);
```

Image Analyst

### Image Analyst (view profile)

on 22 Aug 2014

That's a screenshot again. We don't want axes labels, tick marks, colorbars, etc. - just the image itself. Save your image variable in a .mat file and attach the .mat file.

And I don't see how "plot(c, r, 'ro')", which plots a red circle over every nan value, turns the land from dark blue to black.

Michael

### Michael (view profile)

on 22 Aug 2014

I tried but the .mat/.fig file is too large to attach to this forum.

I interactively selected the red circles within the plot and changed the line width from 6 -> 0.5 and changed the color to black and it gave me the picture attached above.

Kelly Kearney

### Kelly Kearney (view profile)

on 22 Aug 2014

If the NaN mask is in place, I'll still argue that it's much more straightforward to just use pcolor than trying to replicate the same appearance with contortions of image and plot.

```figure;
axes('color', 'k');
pcolor(data);
```

on 5 Dec 2014

I turned Kelly's inpolygon solution into a function called landmask. It's worth noting that downsampling the coast line does make computation faster, but it introduces an error: Each land mass is separated by a row of NaNs in the coast line arrays. If you skip over a NaN row, land masses get conjoined. I included a workaround to that problem in the landmask function.

#### Join the 15-year community celebration.

Play games and win prizes!

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

### Discover what MATLAB® can do for your career.

Apply Today

New to MATLAB?

Learn MATLAB today!