Robochameleon  v1.0
patchline.m
1 function p = patchline(xs,ys,varargin)
2 % Plot lines as patches (efficiently)
3 %
4 % SYNTAX:
5 % patchline(xs,ys)
6 % patchline(xs,ys,zs,...)
7 % patchline(xs,ys,zs,'PropertyName',propertyvalue,...)
8 % p = patchline(...)
9 %
10 % PROPERTIES:
11 % Accepts all parameter-values accepted by PATCH.
12 %
13 % DESCRIPTION:
14 % p = patchline(xs,ys,zs,'PropertyName',propertyvalue,...)
15 % Takes a vector of x-values (xs) and a same-sized
16 % vector of y-values (ys). z-values (zs) are
17 % supported, but optional; if specified, zs must
18 % occupy the third input position. Takes all P-V
19 % pairs supported by PATCH. Returns in p the handle
20 % to the resulting patch object.
21 %
22 % NOTES:
23 % Note that we are drawing 0-thickness patches here,
24 % represented only by their edges. FACE PROPERTIES WILL
25 % NOT NOTICEABLY AFFECT THESE OBJECTS! (Modify the
26 % properties of the edges instead.)
27 %
28 % LINUX (UNIX) USERS: One test-user found that this code
29 % worked well on his Windows machine, but crashed his
30 % Linux box. We traced the problem to an openGL issue;
31 % the problem can be fixed by calling 'opengl software'
32 % in your <http://www.mathworks.com/help/techdoc/ref/startup.html startup.m>.
33 % (That command is valid at startup, but not at runtime,
34 % on a unix machine.)
35 %
36 % EXAMPLES:
37 %%% Example 1:
38 %
39 % n = 10;
40 % xs = rand(n,1);
41 % ys = rand(n,1);
42 % zs = rand(n,1)*3;
43 % plot3(xs,ys,zs,'r.')
44 % xlabel('x');ylabel('y');zlabel('z');
45 % p = patchline(xs,ys,zs,'linestyle','--','edgecolor','g',...
46 % 'linewidth',3,'edgealpha',0.2);
47 %
48 %%% Example 2: (Note "hold on" not necessary here!)
49 %
50 % t = 0:pi/64:4*pi;
51 % p(1) = patchline(t,sin(t),'edgecolor','b','linewidth',2,'edgealpha',0.5);
52 % p(2) = patchline(t,cos(t),'edgecolor','r','linewidth',2,'edgealpha',0.5);
53 % l = legend('sine(t)','cosine(t)');
54 % tmp = sort(findobj(l,'type','patch'));
55 % for ii = 1:numel(tmp)
56 % set(tmp(ii),'facecolor',get(p(ii),'edgecolor'),'facealpha',get(p(ii),'edgealpha'),'edgecolor','none')
57 % end
58 %
59 %%% Example 3 (requires Image Processing Toolbox):
60 %%% (NOTE that this is NOT the same as showing a transparent image on
61 %%% of the existing image. (That functionality is
62 %%% available using showMaskAsOverlay or imoverlay).
63 %%% Instead, patchline plots transparent lines over
64 %%% the image.)
65 %
66 % img = imread('rice.png');
67 % imshow(img)
68 % img = imtophat(img,strel('disk',15));
69 % grains = im2bw(img,graythresh(img));
70 % grains = bwareaopen(grains,10);
71 % edges = edge(grains,'canny');
72 % boundaries = bwboundaries(edges,'noholes');
73 % cmap = jet(numel(boundaries));
74 % ind = randperm(numel(boundaries));
75 % for ii = 1:numel(boundaries)
76 % patchline(boundaries{ii}(:,2),boundaries{ii}(:,1),...
77 % 'edgealpha',0.2,'edgecolor',cmap(ind(ii),:),'linewidth',3);
78 % end
79 %
80 % Written by Brett Shoelson, PhD
81 % brett.shoelson@mathworks.com
82 % 5/31/2012
83 %
84 % Revisions:
85 % 6/26 Improved rice.png example, modified FEX image.
86 %
87 % Copyright 2012 MathWorks, Inc.
88 %
89 % See also: patch, line, plot
90 
91 [zs,PVs] = parseInputs(varargin{:});
92 if rem(numel(PVs),2) ~= 0
93  % Odd number of inputs!
94  error('patchline: Parameter-Values must be entered in valid pairs')
95 end
96 
97 % Facecolor = 'k' is (essentially) ignored here, but syntactically necessary
98 if isempty(zs)
99  p = patch([xs(:);NaN],[ys(:);NaN],'k');
100 else
101  p = patch([xs(:);NaN],[ys(:);NaN],[zs(:);NaN],'k');
102 end
103 
104 % Apply PV pairs
105 for ii = 1:2:numel(PVs)
106  set(p,PVs{ii},PVs{ii+1})
107 end
108 if nargout == 0
109  clear p
110 end
111 
112 function [zs,PVs] = parseInputs(varargin)
113 if isnumeric(varargin{1})
114  zs = varargin{1};
115  PVs = varargin(2:end);
116 else
117  PVs = varargin;
118  zs = [];
119 end