File Exchange

image thumbnail

Hatchfill

version 1.11 (55.1 KB) by

Fills an area with hatching or speckling.

4.92308
14 Ratings

134 Downloads

Updated

View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

In MATLAB, there are many functions that create regions filled with solid colors (e.g. contourf, area, bar). To do this, a function creates "patch objects" and assigns a single color to each one. Instead of a solid fill, one often wants to fill a patch with a hatch or speckle pattern instead. MATLAB has no built-in way to do this.

The hatchfill function fills patch objects with hatching or speckling. In most cases, adding hatching to a 2D plot requires only three lines of code. For example:

[c,h] = contourf(x,y,z,[0 0]);
hp = findobj(h,'type','patch');
hatchfill(hp);

This fills the zero contour with hatching. Hatchfill takes additional parameters if custom patterns are desired. This package incorporates code from Rich Pawlowicz, Iram Weinstein, and Kirill Pankratov.

Comments and Ratings (29)

Yan Jiang

Lao Li

Lao Li (view profile)

Kesh Ikuma

Kesh Ikuma (view profile)

I just upped hatchfill2, which updates hatchfill with post-R2014b support (adds bar and surface objects) for anyone interested. The input arguments are a bit different than the original but all features are still fully intact. Linked above under Acknowledgements.

BC

BC (view profile)

Has anyone come across this issue and found a fix:

I can fill, speckle, and outspeckle but single and cross don't work and are accompanied by the below error message:

Improper assignment with rectangular empty matrix.
Error in hatchfill (line 176)
        H(j) = line(xhatch,yhatch);

All help is greatly appreciated!

Drecalde

For those who have problems using this for legends after 2014b update. Please consider legendflex(http://www.mathworks.com/matlabcentral/fileexchange/31092-legendflex-m--a-more-flexible--customizable-legend) for plotting.
Works like a charm.

Linus

Linus (view profile)

How can I make this work in R2014b?
"findobj(h1, 'Type', 'patch')" does not see work on handles created by contourf (it returns an empty handle)

dpb

dpb (view profile)

ADDENDUM/ERRATUM -- Spoke slightly too soon...
The fixup given below _does_ solve the legend handle; it for some reason I don't yet full understand trashes the patch regions in the figure, however. Best I've done to date is to add yet another conditional...replace the calls to line() w/ the conditional

  if gca==hax
    H(j) = line(xhatch,yhatch);
  else
    H(j) = plot(hax,xhatch,yhatch);
  end

Also, to prevent changes in y-scale found it necessary to clip the yhatch array returned from hatch_xy(). I put it after the call in the calling routine rather than take the time/trouble to pass the limits or handle to hatch_xy()

[xhatch,yhatch] = hatch_xy(x,y,STYL,ANGLE,SPACING);
% clip limits within the axes limits
ylm=ylim(hax);
yhatch(yhatch<ylm(1))=ylm(1);
yhatch(yhatch>ylm(2))=ylm(2);

This was necessary in my case as there were -eps or thereabouts values returned and with the lower axis at 0 for the bar chart it turned the lower axis limit to -1 instead. That's just rude... :)

Don't think it can hurt in general altho is only needed for cases like this of hatching the boundary region.

dpb

dpb (view profile)

R2012b doesn't draw legends correctly; not sure about earlier releases or later.

Fails owing to use of line() primitive which can't take an axis object and uses current axes by default. Can't force legend object to be current axes.

Fixup is to turn the two line() calls

H(j) = line(xhatch,yhatch,'marker','.','linest','none', ... 'markersize',specksize,'color',linec);

with

H(j) = plot(hax,xhatch,yhatch,'marker','.','linest','none', ...
                    'markersize',specksize,'color',linec);

Still needs the fixup of twimmeh as well, of course.

Ben

Ben (view profile)

It would be great if there was a mapping version of Hatchfill, perhaps "Hatchfillm" for hatching "patchm" objects? Hatchfill doesn't appear to work on map axes.

Edward Byers

Modifications that twimmeh describes are highly recommended - thanks!

David

David (view profile)

Very useful file, but I'm having some trouble with the speckling. I'd like to be able to fill a contour with dots, not just outline it. It would be nice if the function were able to do this by itself instead of the user having to, through trial and error.

David

David (view profile)

Taylor Sansom

After a little more editing to hatch_xy as twimmeh described, the legend looks great and the angles work fine.

Cheers!

Taylor Sansom

Thank you very much for this, seems to work like a charm in most applications except for the legend.

I can get the hatching in the legend by doing what twimmeh said (May 2), however the angle doesn't work when hatching in the legend. I can only get horizontal or vertical lines instead of the 45 degree angle that is on my bars.

leg=legend('1-Month','1-Year','5-Year');
legpatch=findobj(leg,'type','patch');
hatchfill(legpatch(3),'single',45,1,'blue')
hatchfill(legpatch(2),'single',45,1,'green')
hatchfill(legpatch(1),'single',45,1,'red')

Any idea how to get the 45 degree angle in the legend?

Bendix

Bendix (view profile)

Seems like a really great tool but unfortunately I don't manage to get it working for the problem I needed it for:

I have a 2D-matrix of linear trends (slopes) and a logical 2D-matrix of the same size telling whether the trend is significant at position xy. Now I'd like to hatch the regions of (no) significance in a contourf or pcolor plot.
Has anyone any hint why it does not work in this case although I get it working in other cases?

Would be very grateful for help.
Cheers

twimmeh

aaaand if you want the aspect ratio of the hatch pattern to be correct you need to pass the axes handle to the hatch_xy function and replace calls to gca.

nasty, but works:

function [xi,yi,x,y]=hatch_xy(hax,x,y,varargin);
gca = hax;

(and of course updating the relevant hatch_xy call line)

twimmeh

I _believe_ the problem with legend hatching is that the lines are being drawn on the wrong axes.

If you adjust the calls to 'line' in the function to specify the axes parent then it seems to work... at least for me (R2011b).

-----------------------------------------

H(j) = line(xhatch,yhatch,'marker','.','linest','none', ...
              'markersize',specksize,'color',linec,'parent',hax);

and

H(j) = line(xhatch,yhatch,'parent',hax);

-----------------------------------------

%My legend code:

hLegend = legend(...);
hp = findobj(hLegend, 'Type', 'patch');
hatchfill(hp)

This assumes you have only one patch; you need to specify hp(i) in the hatchfill call when there are multiple patches. Also, I've found you need to increase the SPACING parameter for it to look good.

Grey Nearing

I am also curious whether it is possible to get a hatch symbol in the legend. The fix Neil suggested on Jul 17 is not working for me.

Neil Tandon

Neil Tandon (view profile)

  • 1 file
  • 134 downloads
  • 4.92308

Thank you Dan, I added an additional check for axes that are only one level up.

Dan K

Dan K (view profile)

In order for this to work for my patches (created using jbfill.m, a FileExchange script), I needed to modify line 95 because the axis handle was only one level up from the patch handle. Perhaps there should be a warning issued or some kind of additional handling if the handle two levels up is not an axis (in my case it was the figure handle).

Then this worked great! Thank you for a terrific m file!

Bruno

Bruno (view profile)

How do I use this for 'bar'?

Bruno

Bruno (view profile)

@Neil and Matt: It still does not work! How do I get a hatched patch symbol in the legend?

Neil Tandon

Neil Tandon (view profile)

  • 1 file
  • 134 downloads
  • 4.92308

Matt - you could try something like...
h = legend('patch1','patch2');
hp = findobj(h,'type','patch');
hatchfill(hp(1));
hatchfill(hp(2));

Matt

Matt (view profile)

The legend doesn't work they way i'd like. for example:

figure;hold on;patch([rand(4,1)],[rand(4,1)],'r','facealpha',.2)
h = patch(rand(4,1),rand(4,1),'b');
hatchfill(h);
legend('patch1','patch2')

can you get a little hatched patch symbol in the legend?

Andrew

Andrew (view profile)

Great script, the latest update functions perfectly for my needs. Thank you.

Neil Tandon

Neil Tandon (view profile)

  • 1 file
  • 134 downloads
  • 4.92308

Thanks Dmytro. I fixed this bug.

I tried:
% =============================
f = figure;
MyColor2fade = 0.6*[1 1 1];
x0d = 3;
ulims = [1 2];
p(1) = patch([x0d,x0d,1,1],[ulims(1),ulims(2),ulims(2), ulims(1)], MyColor2fade,'EdgeColor', 'none','Parent',gca);
hatchfill(p(1))
% =============================
Result: only the left top part of the patch is hatched

Updates

1.11

Added additional check for axes that are only one level up. (Suggested by Dan K.)

1.10

Consolidated code into single file.

1.9

Simplified code.

1.7

Updated description.

1.6

Fixed bug reported by Dmytro Lituiev.

1.5

Updated description

1.4

Minor bug fix.

1.3

Now is compatible with logarithmic axes.

1.2

Polished the examples/documentation a little.

1.1

A little housecleaning...

MATLAB Release
MATLAB 7.11 (R2010b)
Acknowledgements

Inspired by: hatch.m

Inspired: Hatchfill2, kristinbranson/JAABA, Optometrika

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video