Fill a single contour

  • Follow


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.
0
Reply Chuck37 9/23/2010 5:38:06 PM

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.
0
Reply ImageAnalyst 9/23/2010 5:58:26 PM


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?
0
Reply Chuck37 9/23/2010 6:07:04 PM

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?
0
Reply ImageAnalyst 9/23/2010 6:11:33 PM

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?
0
Reply Walter 9/23/2010 6:30:07 PM

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.
0
Reply Chuck37 9/23/2010 7:02:49 PM

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.
0
Reply Chuck37 9/23/2010 7:08:07 PM

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.
0
Reply roberson (2852) 9/24/2010 5:44:56 PM

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.
0
Reply Chuck37 9/24/2010 11:05:37 PM

On Sep 24, 7:05=A0pm, "Chuck37 " <chuck3...@yahooremovethis.com> wrote:
> What I wanted is quite simple to explain. =A0Say I have XY data in a matr=
ix. =A0I, for example, want to color all regions with values less than 5. =
=A0Contour(XY,[5 5]) outlines those regions. =A0Contourf will color the reg=
ions > 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 co=
ntour matrix, see help contourc) to pull out and run PATCH on each individu=
al closed contour. =A0It 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 =3D 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 =3D 'C:\Program Files\MATLAB\R2010a\toolbox\images\imdemos';
baseFileName =3D 'cameraman.tif';
fullFileName =3D fullfile(folder, baseFileName);
grayImage =3D imread(fullFileName);
% create the colormap
grayRamp =3D linspace(0,1,256);
cmap =3D [grayRamp; grayRamp; grayRamp]';
rowsToMakeGreen =3D 50;
cmap (1:rowsToMakeGreen, :) =3D 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 =3D 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 =3D 'C:\Program Files\MATLAB\R2010a\toolbox\images\imdemos';
baseFileName =3D 'cameraman.tif';
fullFileName =3D fullfile(folder, baseFileName);
grayImage =3D imread(fullFileName);
% Get the dimensions of the image.  numberOfColorBands should be =3D 1.
[rows columns numberOfColorBands] =3D 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 =3D grayImage < 50;
% Initialize a new color image.
redPlane =3D grayImage;
greenPlane =3D grayImage;
bluePlane =3D grayImage;
% make them green.
redPlane(darkPixels) =3D 0;
greenPlane(darkPixels) =3D 255;
bluePlane(darkPixels) =3D 0;
% Build up the rgb color image from the individual color planes.
rgbImage =3D 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.
0
Reply imageanalyst (7590) 9/25/2010 3:59:13 AM

9 Replies
345 Views

(page loaded in 0.13 seconds)

Similiar Articles:













7/25/2012 10:58:25 AM


Reply: