Discover MakerZone

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

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Fill a single contour

Subject: Fill a single contour

From: Chuck37

Date: 23 Sep, 2010 17:38:06

Message: 1 of 11

I'm generating a single contour from underlying XY data. I specify the exact level I want. Is there a straightforward way to fill this contour kind of like PATCH or FILL would do? I'm overlaying this on a pcolor plot, so I can't paint the outside region white or anything like that.

PATCH almost works, but it breaks down when there are multiple regions. The contour data also seems to outline the perimeter of the data (the pcolor data isn't necessarily covering the same region).

Thanks.

Subject: Fill a single contour

From: ImageAnalyst

Date: 23 Sep, 2010 17:58:26

Message: 2 of 11

Chuck37
I never use pcolor. I just don't like the fact that there is one
fewer square in each direction than I have. If you have the Image
Processing Toolbox, you can use poly2mask() to create a binary image,
then you can assign that to your image, or do a variety of other
things.

Subject: Fill a single contour

From: Chuck37

Date: 23 Sep, 2010 18:07:04

Message: 3 of 11

ImageAnalyst <imageanalyst@mailinator.com> wrote in message <55686517-6a00-477a-906d-542580ac87ab@m16g2000vbs.googlegroups.com>...
> Chuck37
> I never use pcolor. I just don't like the fact that there is one
> fewer square in each direction than I have. If you have the Image
> Processing Toolbox, you can use poly2mask() to create a binary image,
> then you can assign that to your image, or do a variety of other
> things.

I don't have the image toolbox. I can use imagesc anyway to get around the pcolor weirdness if I need to. I actually misspoke though, I'm really using a surface because that's the only way I could figure out to overlay contour and pcolor, I draw the contour on the Z=0 plane and either play with the alpha of the surface or look from an angle where the Z=0 is in front of the surface...

Regarding my original problem, I tried using the data underlying the contour, putting NaN's outside my region of interest and setting the rest to a value and then making a surface plot of that. Didn't really work because (a) it looks pixelated, and (b) the color it selects is messed up because it just picks off of the existing colormap. (b) could be worked around with some effort, but not (a).

Other ideas?

Subject: Fill a single contour

From: ImageAnalyst

Date: 23 Sep, 2010 18:11:33

Message: 4 of 11

Can you explain this more:
"PATCH almost works, but it breaks down when there are multiple
regions. "
What breaks down exactly? What kind of contours cause patch to fail?

Subject: Fill a single contour

From: Walter Roberson

Date: 23 Sep, 2010 18:30:07

Message: 5 of 11

On 10-09-23 01:07 PM, Chuck37 wrote:

> Regarding my original problem, I tried using the data underlying the
> contour, putting NaN's outside my region of interest and setting the
> rest to a value and then making a surface plot of that. Didn't really
> work because (a) it looks pixelated, and (b) the color it selects is
> messed up because it just picks off of the existing colormap. (b) could
> be worked around with some effort, but not (a).

Could you highlight the difference between what you want and what contourf()
would provide ? Could you also describe how patch "breaks down when there are
multiple regions" ?

Are you aware that contour() returns handles to patches, and that for any of
those patches, you could set the FaceColor property?

Subject: Fill a single contour

From: Chuck37

Date: 23 Sep, 2010 19:02:49

Message: 6 of 11

Walter Roberson <roberson@hushmail.com> wrote in message <i7g6g7$nbp$1@canopus.cc.umanitoba.ca>...
> On 10-09-23 01:07 PM, Chuck37 wrote:
>
> > Regarding my original problem, I tried using the data underlying the
> > contour, putting NaN's outside my region of interest and setting the
> > rest to a value and then making a surface plot of that. Didn't really
> > work because (a) it looks pixelated, and (b) the color it selects is
> > messed up because it just picks off of the existing colormap. (b) could
> > be worked around with some effort, but not (a).
>
> Could you highlight the difference between what you want and what contourf()
> would provide ? Could you also describe how patch "breaks down when there are
> multiple regions" ?
>
> Are you aware that contour() returns handles to patches, and that for any of
> those patches, you could set the FaceColor property?

My contour call looks like [c,h]=contour(x,y,Z,[level level]). It gives a single handle back to the contour at the specified level. This contour may have multiple enclosed regions though. If I do something like plot(c(1,:),c(2,:)) it looks kind of like the contour plot, but there are extraneous lines going around connecting the different regions together and connecting to the edge of the x,y range. So, if I feed it to patch it gives garbage back.

Contourf will color the interior region (the one I want to color) white and color the outside (which I want untouched) blue.

I don't believe that contour gives a handle to each patch, but to each contour level. Correct me if I'm wrong. I get only one value in "h" even though there are multiple enclosed regions. Thanks.

Subject: Fill a single contour

From: Chuck37

Date: 23 Sep, 2010 19:08:07

Message: 7 of 11

Looking in the help for contourc, I see that there is side information tucked into the contour matrix returned by contour. I think I should be able to parse it to determine the points for each independent region and call patch on those.

Subject: Fill a single contour

From: Walter Roberson

Date: 24 Sep, 2010 17:44:56

Message: 8 of 11

On 10-09-23 02:02 PM, Chuck37 wrote:

> My contour call looks like [c,h]=contour(x,y,Z,[level level]). It gives
> a single handle back to the contour at the specified level. This contour
> may have multiple enclosed regions though. If I do something like
> plot(c(1,:),c(2,:)) it looks kind of like the contour plot, but there
> are extraneous lines going around connecting the different regions
> together and connecting to the edge of the x,y range. So, if I feed it
> to patch it gives garbage back.
>
> Contourf will color the interior region (the one I want to color) white
> and color the outside (which I want untouched) blue.
>
> I don't believe that contour gives a handle to each patch, but to each
> contour level. Correct me if I'm wrong. I get only one value in "h" even
> though there are multiple enclosed regions. Thanks.

A terminology clash here.

The h handle returned by contour() is that of a hggroup object. That hggroup
object has a number of children; each of those children is an object of type
'patch'. The properties of each of those patch objects can be adjusted.

contourf is defined to color the regions *less* than the first specified
contour level as white; the levels above that are coloured according to
indices into the colormap. Possibly you are wanting to reverse the normal
contour filling; if so, then you will have a bit of a problem.

I find that in 2008b Linux 64, that contourf() with a single level fills
_everything_ with the same color. The work-around I have found for this is to
use contour() instead, and then to set() the 'fill' property of the hggroup
object returned ("h") to 'on'.

What I was suggesting earlier was that the patch objects (the children of the
hggroup) could have their FaceColor set to the desired fill color. Although
those FaceColor properties do start out as 'none', it turns out that setting
them does not result in the face being filled, but setting the 'fill' property
of the hggroup fills all the faces at once. I would need to dig in to the
workings of hggroups and patches to see whether single patches could be
filled. However, your discussion of what gets colored suggests that you want
what would normally be _outside_ of the contour to be filled, and that's not
something that would be possible with this technique.

I would have to think of how best to do a reverse fill. The only thing that
comes to mind at the moment would be to contour() the negative of the data
with the negative of the desired level, and then to go through all of the
patch() children of the hggroup and set their ZData to the negative of the
existing matrix. I'm not sure that would work, though, as the hggroup has a
ContourMatrix property whose purpose I have not yet figured out.

Subject: Fill a single contour

From: Chuck37

Date: 24 Sep, 2010 23:05:37

Message: 9 of 11

What I wanted is quite simple to explain. Say I have XY data in a matrix. I, for example, want to color all regions with values less than 5. Contour(XY,[5 5]) outlines those regions. Contourf will color the regions > 5 a color and the region I care about white.

The answer I found is to use contourc to get the contour data, then run a while loop on that data (it indicates the closed contour regions in the contour matrix, see help contourc) to pull out and run PATCH on each individual closed contour. It works well.

Thanks everyone for the help.

Subject: Fill a single contour

From: ImageAnalyst

Date: 25 Sep, 2010 03:59:13

Message: 10 of 11

On Sep 24, 7:05 pm, "Chuck37 " <chuck3...@yahooremovethis.com> wrote:
> What I wanted is quite simple to explain.  Say I have XY data in a matrix.  I, for example, want to color all regions with values less than 5.  Contour(XY,[5 5]) outlines those regions.  Contourf will color the regions > 5 a color and the region I care about white.
>
> The answer I found is to use contourc to get the contour data, then run a while loop on that data (it indicates the closed contour regions in the contour matrix, see help contourc) to pull out and run PATCH on each individual closed contour.  It works well.
>
> Thanks everyone for the help.

-------------------------------------------------------------------
That's not the way I'd do it. First of all, patch covers the pixels
with a patch of color in the overlay above the image. It does not
actually change the matrix to green - which may be okay, if that's
what you want. But drawing potentially hundreds or thousands of
patches all over the place doesn't seem very efficient. A better way
to do what you just said is to simply display the array with image, or
imagesc, or imshow, and use a color map to pseudocolor all pixels less
than some level to be green. Like this:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 14;

% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
% Read in a standard MATLAB gray scale demo image.
folder = 'C:\Program Files\MATLAB\R2010a\toolbox\images\imdemos';
baseFileName = 'cameraman.tif';
fullFileName = fullfile(folder, baseFileName);
grayImage = imread(fullFileName);
% create the colormap
grayRamp = linspace(0,1,256);
cmap = [grayRamp; grayRamp; grayRamp]';
rowsToMakeGreen = 50;
cmap (1:rowsToMakeGreen, :) = repmat([0 1 0], [rowsToMakeGreen 1]); %
0 - 49 graylevels will be green.
% Display the original gray scale image.
imshow(grayImage, cmap);
title('Original Grayscale Image', 'FontSize', fontSize);
set(gcf, 'Position', get(0,'Screensize')); % Enlarge figure to full
screen.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')




Displaying with a colormap does not change matrix values, only how
they're displayed. If you actually want to change the matrix (pixel)
values you'll have to create an rgb image and then assign the pixels
to green. Run this example. I changed the value for green to "less
than 50" so you could see some green on the image, but you could use 5
if you want. (You may have to join some lines if the newsreader
splits them into two, which it will do for long lines.)

clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 14;

% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
% Read in a standard MATLAB gray scale demo image.
folder = 'C:\Program Files\MATLAB\R2010a\toolbox\images\imdemos';
baseFileName = 'cameraman.tif';
fullFileName = fullfile(folder, baseFileName);
grayImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(2, 1, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
set(gcf, 'Position', get(0,'Screensize')); % Enlarge figure to full
screen.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')

% Find pixels less than, say 50, and color them green.
darkPixels = grayImage < 50;
% Initialize a new color image.
redPlane = grayImage;
greenPlane = grayImage;
bluePlane = grayImage;
% make them green.
redPlane(darkPixels) = 0;
greenPlane(darkPixels) = 255;
bluePlane(darkPixels) = 0;
% Build up the rgb color image from the individual color planes.
rgbImage = cat(3, redPlane, greenPlane, bluePlane); % Initialize
subplot(2, 1, 2);
imshow(rgbImage, []);
title('Color Image with pixels less than 50 as green', 'FontSize',
fontSize);

It's a lot of code, but it's there just to be explicit and make you
understand. It's a tutorial - don't be afraid of it. Just go through
line by line and you'll understand.

Subject: Fill a single contour

From: Theo Olsthoorn

Date: 14 May, 2014 20:48:09

Message: 11 of 11

% The previous answers contain a lot of useless bla bla, which should be prevented; it is of no use
% Here is a concrete answer:
ax1 = axes( .... properties of axes en extent ...);
ax2= axes( ... same properties and extent ..., 'color','none'); % transparent
            contourf(ax1,X,Y,DEM,range); % nicely fill contours of whatever, like a DEM
[~,h] = contourf(ax2,X,Y,DEM-elev,[0 0],'b'); % fill zero contour blue
set(get(h,'children'),'faceColor','b');

% It only works with the extra axes, recontouring on the same axis does to show the filled area.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us