0、起因

网上能够搜索的到的资源,都没办法支持Matlab在柱状图里填充线条或者没办法很好的为填充线条的柱状图添加图例,经过研究我发现了一种可以完美填充柱状图的方法

1、导入函数

首先需要引入三个matlab的函数

hatchfill2.m函数

function H = hatchfill2(A,varargin)
% HATCHFILL2 Hatching and speckling of patch objects
%   HATCHFILL2(A) fills the patch(es) with handle(s) A. A can be a vector
%   of handles or a single handle. If A is a vector, then all objects of A
%   should be part of the same group for predictable results. The hatch
%   consists of black lines angled at 45 degrees at 40 hatching lines over
%   the axis span with no color filling between the lines.
%
%   A can be handles of patch or hggroup containing patch objects for
%   Pre-R2014b release. For HG2 releases, 'bar' and 'contour' objects are
%   also supported.
%
%   Hatching line object is actively formatted. If A, axes, or figure size
%   is modified, the hatching line object will be updated accordingly to
%   maintain the specified style.
%
%   HATCHFILL2(A,STYL) applies STYL pattern with default paramters. STYL
%   options are:
%      'single'     single lines (the default)
%      'cross'      double-crossed hatch
%      'speckle'    speckling inside the patch boundary
%      'outspeckle' speckling outside the boundary
%      'fill'       no hatching
%
%   HATCHFILL2(A,STYL,Option1Name,Option1Value,...) to customize the
%   hatching pattern
%
%       Name       Description
%      --------------------------------------------------------------------
%      HatchStyle       Hatching pattern (same effect as STYL argument)
%      HatchAngle       Angle of hatch lines in degrees (45)
%      HatchDensity     Number of hatch lines between axis limits
%      HatchOffset      Offset hatch lines in pixels (0)
%      HatchColor       Color of the hatch lines, 'auto' sets it to the
%                       EdgeColor of A
%      HatchLineStyle   Hatch line style
%      HatchLineWidth   Hatch line width
%      SpeckleWidth         Width of speckling region in pixels (7)
%      SpeckleDensity       Density of speckle points (1)
%      SpeckleMarkerStyle   Speckle marker style
%      SpeckleFillColor     Speckle fill color
%      HatchVisible     [{'auto'}|'on'|'off'] sets visibility of the hatch
%                       lines. If 'auto', Visibile option is synced to
%                       underlying patch object
%      HatchSpacing     (Deprecated) Spacing of hatch lines (5)
%
%   In addition, name/value pairs of any properties of A can be specified
%
%   H = HATCHFILL2(...) returns handles to the line objects comprising the
%   hatch/speckle.
%
%   Examples:
%       Gray region with hatching:
%       hh = hatchfill2(a,'cross','HatchAngle',45,'HatchSpacing',5,'FaceColor',[0.5 0.5 0.5]);
%
%       Speckled region:
%       hatchfill2(a,'speckle','HatchAngle',7,'HatchSpacing',1);% Copyright 2015-2018 Takeshi Ikuma
% History:
% rev. 7 : (01-10-2018)
%   * Added support for 3D faces
%   * Removed HatchSpacing option
%   * Added HatchDensity option
%   * Hatching is no longer defined w.r.t. pixels. HatchDensity is defined
%     as the number of hatch lines across an axis limit. As a result,
%     HatchAngle no longer is the actual hatch angle though it should be
%     close.
%   * [known bug] Speckle hatching style is not working
% rev. 6 : (07-17-2016)
%   * Fixed contours object hatching behavior, introduced in rev.5
%   * Added ContourStyle option to enable fast drawing if contour is convex
% rev. 5 : (05-12-2016)
%   * Fixed Contour with NaN data point disappearnace issue
%   * Improved contours object support
% rev. 4 : (11-18-2015)
%   * Worked around the issue with HG2 contours with Fill='off'.
%   * Removed nagging warning "UseHG2 will be removed..." in R2015b
% rev. 3 : (10-29-2015)
%   * Added support for HG2 AREA
%   * Fixed for HatchColor 'auto' error when HG2 EdgeColor is 'flat'
%   * Fixed listener creation error
% rev. 2 : (10-24-2015)
%   * Added New option: HatchVisible, SpeckleDensity, SpeckleWidth
%     (SpeckleDensity and SpeckleWidtha are separated from HatchSpacing and
%     HatchAngle, respectively)
% rev. 1 : (10-20-2015)
%   * Fixed HG2 contour data extraction bug (was using wrong hidden data)
%   * Fixed HG2 contour color extraction bug
%   * A few cosmetic changes here and there
% rev. - : (10-19-2015) original release
%   * This work is based on Neil Tandon's hatchfill submission
%     (http://www.mathworks.com/matlabcentral/fileexchange/30733)
%     and borrowed code therein from R. Pawlowicz, K. Pankratov, and
%     Iram Weinstein.narginchk(1,inf);
[A,opts,props] = parse_input(A,varargin);drawnow % make sure the base objects are already drawnif verLessThan('matlab','8.4')H = cell(1,numel(A));
elseH = repmat({matlab.graphics.GraphicsPlaceholder},1,numel(A));
end
for n = 1:numel(A)H{n} = newhatch(A(n),opts,props);% if legend of A(n) is shown, add hatching to it as well%    leg = handle(legend(ancestor(A,'axes')));%    hsrc = [leg.EntryContainer.Children.Object];%    hlc = leg.EntryContainer.Children(find(hsrc==A(n),1));%    if ~isempty(hlc)%       hlc = hlc.Children(1); % LegendIcon object%       get(hlc.Children(1))%    end
endif nargout==0clear H
elseH = [H{:}];if numel(H)==numel(A)H = reshape(H,size(A));elseH = H(:);end
endendfunction H = newhatch(A,opts,props)% 0. retrieve pixel-data conversion parameters
% 1. retrieve face & vertex matrices from A
% 2. convert vertex matrix from data to pixels units
% 3. get xdata & ydata of hatching lines for each face
% 4. concatenate lines sandwitching nan's in between
% 5. convert xdata & ydata back to data units
% 6. plot the hatching line% traverse if hggroup/hgtransform
if ishghandle(A,'hggroup')if verLessThan('matlab','8.4')H = cell(1,numel(A));elseH = repmat({matlab.graphics.GraphicsPlaceholder},1,numel(A));endfor n = 1:numel(A.Children)tryH{n} = newhatch(A.Children(n),opts,props);catchendendH = [H{:}];return;
end% Modify the base object property if given
if ~isempty(props)pvalold = sethgprops(A,props);
endtryvislisena = strcmp(opts.HatchVisible,'auto');if vislisenavis = A.Visible;elsevis = opts.HatchVisible;endredraw = strcmp(A.Visible,'off') && ~vislisena;if redrawA.Visible = 'on'; % momentarily make the patch visibledrawnow;end% get the base object's vertices & faces[V,F,FillFcns] = gethgdata(A); % object does not have its patch data readyif redrawA.Visible = 'off'; % momentarily make the patch visibleendif ~isempty(FillFcns)FillFcns{1}();drawnow;[V,F] = gethgdata(A); % object does not have its patch data readyFillFcns{2}();drawnow;end% recompute hatch line data[X,Y,Z] = computeHatchData(handle(ancestor(A,'axes')),V,F,opts);% 6. plot the hatching linecommonprops = {'Parent',A.Parent,'DisplayName',A.DisplayName,'Visible',vis};if ~strcmp(opts.HatchColor,'auto')commonprops = [commonprops {'Color',opts.HatchColor,'MarkerFaceColor',opts.HatchColor}];endif isempty(regexp(opts.HatchStyle,'speckle$','once'))H = line(X,Y,Z,commonprops{:},'LineStyle',opts.HatchLineStyle','LineWidth',opts.HatchLineWidth);elseH = line(X,Y,Z,commonprops{:},'LineStyle','none','Marker',opts.SpeckleMarkerStyle,...'MarkerSize',opts.SpeckleSize,'Parent',A.Parent,'DisplayName',A.DisplayName);endif strcmp(opts.HatchColor,'auto')syncColor(H,A);endif isempty(H)error('Unable to obtain hatching data from the specified object A.');end% 7. Move H so that it is place right above A in parent's uistackp = handle(A.Parent);Hcs = handle(p.Children);[~,idx] = ismember(A,Hcs); % always idx(1)>idx(2) as H was just createdp.Children = p.Children([2:idx-1 1 idx:end]);% if HG1, all done | no dynamic adjustment supportif verLessThan('matlab','8.4')return;end% save the config data & set up the object listenerssetappdata(A,'HatchFill2Opts',opts); % hatching optionssetappdata(A,'HatchFill2Obj',H); % hatching line objectsetappdata(A,'HatchFill2LastData',{V,F}); % last patch datasetappdata(A,'HatchFill2LastVisible',A.Visible); % last sensitive propertiessetappdata(A,'HatchFill2PostMarkedClean',{}); % run this function at the end of the MarkClean callback and set NoAction flagsetappdata(A,'HatchFill2NoAction',false); % no action during next MarkClean callback, callback only clears this flagsetappdata(H,'HatchFill2MatchVisible',vislisena);setappdata(H,'HatchFill2MatchColor',strcmp(opts.HatchColor,'auto'));setappdata(H,'HatchFill2Patch',A); % base object%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Create listeners for active formattingaddlistener(H,'ObjectBeingDestroyed',@hatchBeingDeleted);lis = [addlistener(A,'Reparent',@objReparent)addlistener(A,'ObjectBeingDestroyed',@objBeingDeleted);addlistener(A,'MarkedClean',@objMarkedClean)addlistener(A,'LegendEntryDirty',@(h,evt)[])]; % <- study this latersyncprops = {'Clipping','HitTest','Interruptible','BusyAction','UIContextMenu'};syncprops(~cellfun(@(p)isprop(A,p),syncprops)) = [];for n = 1:numel(syncprops)lis(n+2) = addlistener(A,syncprops{n},'PostSet',@syncProperty);endcatch ME% something went wrong, restore the base object propertiesif ~isempty(props)for pname = fieldnames(pvalold)'name = pname{1};val = pvalold.(name);if iscell(val)pvalold.(name){1}.(name) = pvalold.(name){2};elseA.(name) = pvalold.(name);endendendME.rethrow();
endend%%%%%%%%%% EVENT CALLBACK FUNCTIONS %%%%%%%%%%%%
% Base Object's listeners
% objReparent - also move the hatch object
% ObjectingBeingDestroyed - also destroy the hatch object
% MarkedClean - match color if HatchColor = 'auto'
%             - check if vertex & face changed; if so redraw hatch
%             - check if hatch redraw triggered the event due to object's
%               face not shown; if so clear the flagfunction objMarkedClean(hp,~)
% CALLBACK for base object's MarkedClean event
% check: visibility change, hatching area change, & color changeif getappdata(hp,'HatchFill2NoAction')setappdata(A,'HatchFill2NoAction',false);return;
end% get the main patch object (loops if hggroup or HG2 objects)
H = getappdata(hp,'HatchFill2Obj');rehatch = ~strcmp(hp.Visible,getappdata(hp,'HatchFill2LastVisible'));
if rehatch % if visibility changedsetappdata(hp,'HatchFill2LastVisible',hp.Visible);if strcmp(hp.Visible,'off') % if made hidden, hide hatching as wellif getappdata(H,'HatchFill2MatchVisible')H.Visible = 'off';return; % nothing else to doendend
end% get the patch data
[V,F,FillFcns] = gethgdata(hp);
if ~isempty(FillFcns) % patch does not exist, must momentarily generate itFillFcns{1}();setappdata(A,'HatchFill2PostMarkedClean',FillFcns{2});return;
end
if ~rehatch % if visible already 'on', check for the change in object dataVFlast = getappdata(hp,'HatchFill2LastData');rehatch = ~isequaln(F,VFlast{2}) || ~isequaln(V,VFlast{1});
end% rehatch if patch data/visibility changed
if rehatch % recompute hatch line data[X,Y,Z] = computeHatchData(ancestor(H,'axes'),V,F,getappdata(hp,'HatchFill2Opts'));% update the hatching line dataset(H,'XData',X,'YData',Y,'ZData',Z);% save patch datasetappdata(hp,'HatchFill2LastData',{V,F});
end% sync the color
syncColor(H,hp);% run post callback if specified (expect it to trigger another MarkedClean
% event immediately)
fcn = getappdata(hp,'HatchFill2PostMarkedClean');
if ~isempty(fcn)setappdata(hp,'HatchFill2PostMarkedClean',function_handle.empty);setappdata(hp,'HatchFill2NoAction',true);fcn();return;
endendfunction syncProperty(~,evt)
% sync Visible property to the patch object
hp = handle(evt.AffectedObject); % patch object
hh = getappdata(hp,'HatchFill2Obj');
hh.(evt.Source.Name) = hp.(evt.Source.Name);
endfunction objReparent(hp,evt)
%objReparent event listener callbackpnew = evt.NewValue;
if isempty(pnew)return; % no change?
end% move the hatch line object over as well
H = getappdata(hp,'HatchFill2Obj');
H.Parent = pnew;% make sure to move the hatch line object right above the patch object
Hcs = handle(pnew.Children);
[~,idx] = ismember(hp,Hcs); % always idx(1)>idx(2) as H was just moved
pnew.Children = pnew.Children([2:idx-1 1 idx:end]);endfunction objBeingDeleted(hp,~)
%when base object is deletedif isappdata(hp,'HatchFill2Obj')H = getappdata(hp,'HatchFill2Obj');try % in case H is already deleteddelete(H);catchend
endendfunction hatchBeingDeleted(hh,~)
%when hatch line object (hh) is deletedif isappdata(hh,'HatchFill2Patch')%   remove listeners listening to the patch objecthp = getappdata(hh,'HatchFill2Patch');if isappdata(hp,'HatchFill2Listeners')delete(getappdata(hp,'HatchFill2Listeners'));rmappdata(hp,'HatchFill2Listeners');end
endend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function varargout = computeHatchData(ax,V,F,opts)varargout = cell(1,nargout);if isempty(V) % if patch shownreturn;
endN = size(F,1);
XYZc = cell(2,N);
for n = 1:N % for each face% 2. get xdata & ydata of the vertices of the face in transformed basesf = F(n,:); % get indices to the vertices of the facef(isnan(f)) = [];[v,T,islog] = transform_data(ax,V(f,:),[]); % transform the faceif isempty(v) % face is not hatchablecontinue;end% 2. get xdata & ydata of hatching lines for each faceif any(strcmp(opts.HatchStyle,{'speckle','outsidespeckle'}))xy = hatch_xy(v.',opts.HatchStyle,opts.SpeckleWidth,opts.SpeckleDensity,opts.HatchOffset);elsexy = hatch_xy(v.',opts.HatchStyle,opts.HatchAngle,opts.HatchDensity,opts.HatchOffset);end% 3. revert the bases back to 3D Eucledian spaceXYZc{1,n} = revert_data(xy',T,islog).';
end% 4. concatenate hatch lines across faces sandwitching nan's in between
[XYZc{2,:}] = deal(nan(3,1));
XYZ = cat(2,XYZc{:});% 5. convert xdata & ydata back to data units
[varargout{1:3}] = deal(XYZ(1,:),XYZ(2,:),XYZ(3,:));endfunction tf = issupported(hbase)
% check if all of the given base objects are supportedsupported_objtypes = {'patch','hggroup','bar','contour','area','surface','histogram'};if isempty(hbase)tf = false;
elsetf = ishghandle(hbase,supported_objtypes{1});for n = 2:numel(supported_objtypes)tf(:) = tf | ishghandle(hbase,supported_objtypes{n});endtf = all(tf);
endend% synchronize hatching line color to the patch's edge color if HatchColor =
% 'auto'
function syncColor(H,A)if ~getappdata(H,'HatchFill2MatchColor')% do not syncreturn;
endif ishghandle(A,'patch') || ishghandle(A,'Bar') || ishghandle(A,'area') ...|| ishghandle(A,'surface') || ishghandle(A,'Histogram') %HG2pname = 'EdgeColor';
elseif ishghandle(A,'contour') % HG2pname = 'LineColor';
end
color = A.(pname);
if strcmp(color,'flat')trycolor = double(A.Edge(1).ColorData(1:3)')/255;catchwarning('Does not support CData based edge color.');color = 'k';end
end
H.Color = color;
H.MarkerFaceColor = color;endfunction [V,F,FillFcns] = gethgdata(A)
% Get vertices & face data from the object along with the critical
% properties to observe change in the hatching area% initialize the output variable
F = [];
V = [];
FillFcns = {};if ~isvalid(A) || strcmp(A.Visible,'off')return;
endif ishghandle(A,'patch')V = A.Vertices;F = A.Faces;
elseif ishghandle(A,'bar')[V,F] = getQuadrilateralData(A.Face);
elseif ishghandle(A,'area')[V,F] = getTriangleStripData(A.Face);set(A,'FaceColor','none');
elseif ishghandle(A,'surface') % HG2if strcmp(A.FaceColor,'none')FillFcns = {@()set(A,'FaceColor','w'),@()set(A,'FaceColor','none')};return;end[V,F] = getQuadrilateralData(A.Face);
elseif ishghandle(A,'contour') % HG2% Retrieve data from hidden FacePrims property (a TriangleStrip object)if strcmp(A.Fill,'off')FillFcns = {@()set(A,'Fill','on'),@()set(A,'Fill','off')};return;end[V,F] = getTriangleStripData(A.FacePrims);
elseif ishghandle(A,'histogram') %HG2: Quadrateral underlying data object[V,F] = getQuadrilateralData(A.NodeChildren(4));
endendfunction [V,F] = getQuadrilateralData(A) % surface, bar, histogram,if isempty(A)warning('Cannot hatch the face: Graphics object''s face is not defined.');V = [];F = [];return;
endV = A.VertexData';% If any of the axes is in log scale, V is normalized to wrt the axes
% limits,
V(:) = norm2data(V,A);if ~isempty(A.VertexIndices) % vertices likely reused on multiple quadrilateralsI = A.VertexIndices;Nf = numel(I)/4; % has to be divisible by 4
else %every 4 consecutive vertices defines a quadrilateralNv = size(V,1);Nf = Nv/4;I = 1:Nv;
end
F = reshape(I,4,Nf)';
if ~isempty(A.StripData) % hack workaroundF(:) = F(:,[1 2 4 3]);
end
tryif ~any(all(V==V(1,:))) % not on any Euclidian plane% convert quadrilateral to triangle stripsF = [F(:,1:3);F(:,[1 3 4])];end
catch % if implicit array expansion is not supported (<R2016b)if all(V(:,1)~=V(1,1)) || all(V(:,2)~=V(1,2)) || all(V(:,3)~=V(1,3)) % not on any Euclidian plane% convert quadrilateral to triangle stripsF = [F(:,1:3) F(:,[1 3 4])];end
endendfunction [V,F] = getTriangleStripData(A) % area & contourif isempty(A)warning('Cannot hatch the face: Graphics object''s face is not defined.');V = [];F = [];return;
endV = A.VertexData';
I = double(A.StripData);% If any of the axes is in log scale, V is normalized to wrt the axes
% limits,
V(:) = norm2data(V,A);N = numel(I)-1; % # of faces
m = diff(I);
M = max(m);
F = nan(N,M);
for n = 1:Nidx = I(n):(I(n+1)-1);if mod(numel(idx),2) % oddidx(:) = idx([1:2:end end-1:-2:2]);else % evenidx(:) = idx([1:2:end-1 end:-2:2]);endF(n,1:numel(idx)) = idx;
end
end% if graphical objects are given normalized to the axes
function V = norm2data(V,A)
ax = ancestor(A,'axes');
inlog = strcmp({ax.XScale ax.YScale ax.ZScale},'log');
if any(inlog)lims = [ax.XLim(:) ax.YLim(:) ax.ZLim(:)];dirs = strcmp({ax.XDir ax.YDir ax.ZDir},'normal');for n = 1:3 % for each axisif inlog(n)lims(:,n) = log10(lims(:,n));endV(:,n) = V(:,n)*diff(lims(:,n));if dirs(n)V(:,n) = V(:,n) + lims(1,n);elseV(:,n) = lims(2,n) - V(:,n);endif inlog(n)V(:,n) = 10.^V(:,n);endend
end
endfunction pvalold = sethgprops(A,props)
% grab the common property names of the base objectspnames = fieldnames(props);
if ishghandle(A,'hggroup')gpnames = fieldnames(set(A));[tf,idx] = ismember(gpnames,pnames);idx(~tf) = [];for i = idx'pvalold.(pnames{i}) = A.(pnames{i});A.(pnames{i}) = props.(pnames{i});endprops = rmfield(props,pnames(idx));h = handle(A.Children);for n = 1:numel(h)pvalold1 = sethgprops(h(n),props);ponames = fieldnames(pvalold1);for k = 1:numel(ponames)pvalold.(ponames{k}) = {h(n) pvalold1.(ponames{k})};endend
elsefor n = 1:numel(pnames)pvalold.(pnames{n}) = A.(pnames{n});A.(pnames{n}) = props.(pnames{n});end
endendfunction xydatai = hatch_xy(xydata,styl,angle,step,offset)
%
% M_HATCH Draws hatched or speckled interiors to a patch
%
%    M_HATCH(LON,LAT,STYL,ANGLE,STEP,...line parameters);
%
% INPUTS:
%     X,Y - vectors of points.
%     STYL - style of fill
%     ANGLE,STEP - parameters for style
%
%     E.g.
%
%      'single',45,5  - single cross-hatch, 45 degrees,  5 points apart
%      'cross',40,6   - double cross-hatch at 40 and 90+40, 6 points apart
%      'speckle',7,1  - speckled (inside) boundary of width 7 points, density 1
%                               (density >0, .1 dense 1 OK, 5 sparse)
%      'outspeckle',7,1 - speckled (outside) boundary of width 7 points, density 1
%                               (density >0, .1 dense 1 OK, 5 sparse)
%
%
%      H=M_HATCH(...) returns handles to hatches/speckles.
%
%      [XI,YI,X,Y]=MHATCH(...) does not draw lines - instead it returns
%      vectors XI,YI of the hatch/speckle info, and X,Y of the original
%      outline modified so the first point==last point (if necessary).
%
%     Note that inside and outside speckling are done quite differently
%     and 'outside' speckling on large coastlines can be very slow.%
% Hatch Algorithm originally by K. Pankratov, with a bit stolen from
% Iram Weinsteins 'fancification'. Speckle modifications by R. Pawlowicz.
%
% R Pawlowicz 15/Dec/2005I = zeros(1,size(xydata,2));% face vertices are not always closed
if any(xydata(:,1)~=xydata(:,end))xydata(:,end+1) = xydata(:,1);I(end+1) = I(1);
endif any(strcmp(styl,{'speckle','outspeckle'}))angle = angle*(1-I);
endswitch stylcase 'single'xydatai = drawhatch(xydata,angle,1/step,0,offset);case 'cross'xydatai = [...drawhatch(xydata,angle,1/step,0,offset) ...drawhatch(xydata,angle+90,1/step,0,offset)];case 'speckle'xydatai = [...drawhatch(xydata,45,   1/step,angle,offset) ...drawhatch(xydata,45+90,1/step,angle,offset)];case 'outspeckle'xydatai = [...drawhatch(xydata,45,   1/step,-angle,offset) ...drawhatch(xydata,45+90,1/step,-angle,offset)];inside = logical(inpolygon(xydatai(1,:),xydatai(2,:),x,y)); % logical needed for v6!xydatai(:,inside) = [];otherwisexydatai = zeros(2,0);
endend%%%function xydatai = drawhatch(xydata,angle,step,speckle,offset)
% xydata is given as 2xN matrix, x on the first row, y on the second% Idea here appears to be to rotate everthing so lines will be
% horizontal, and scaled so we go in integer steps in 'y' with
% 'points' being the units in x.
% Center it for "good behavior".% rotate first about (0,0)
ca = cosd(angle); sa = sind(angle);
u = [ca sa]*xydata;              % Rotation
v = [-sa ca]*xydata;% translate to the grid point nearest to the centroid
u0 = round(mean(u)/step)*step; v0 = round(mean(v)/step)*step;
x = (u-u0); y = (v-v0)/step+offset;    % plus scaling and offsetting% Compute the coordinates of the hatch line ...............
yi = ceil(y);
yd = [diff(yi) 0]; % when diff~=0 we are crossing an integer
fnd = find(yd);    % indices of crossings
dm = max(abs(yd)); % max possible #of integers between points% This is going to be pretty space-inefficient if the line segments
% going in have very different lengths. We have one column per line
% interval and one row per hatch line within that interval.
%
A = cumsum( repmat(sign(yd(fnd)),dm,1), 1);% Here we interpolate points along all the line segments at the
% correct intervals.
fnd1 = find(abs(A)<=abs( repmat(yd(fnd),dm,1) ));
A  = A+repmat(yi(fnd),dm,1)-(A>0);
xy = (x(fnd+1)-x(fnd))./(y(fnd+1)-y(fnd));
xi = repmat(x(fnd),dm,1)+(A-repmat(y(fnd),dm,1) ).*repmat(xy,dm,1);
yi = A(fnd1);
xi = xi(fnd1);% Sorting points of the hatch line ........................
%%yi0 = min(yi); yi1 = max(yi);
% Sort them in raster order (i.e. by x, then by y)
% Add '2' to make sure we don't have problems going from a max(xi)
% to a min(xi) on the next line (yi incremented by one)
xi0 = min(xi); xi1 = max(xi);
ci = 2*yi*(xi1-xi0)+xi;
[~,num] = sort(ci);
xi = xi(num); yi = yi(num);% if this happens an error has occurred somewhere (we have an odd
% # of points), and the "fix" is not correct, but for speckling anyway
% it really doesn't make a difference.
if rem(length(xi),2)==1xi = [xi; xi(end)];yi = [yi; yi(end)];
end% Organize to pairs and separate by  NaN's ................
li = length(xi);
xi = reshape(xi,2,li/2);
yi = reshape(yi,2,li/2);% The speckly part - instead of taking the line we make a point some
% random distance in.
if length(speckle)>1 || speckle(1)~=0if length(speckle)>1% Now we get the speckle parameter for each line.% First, carry over the speckle parameter for the segment%   yd=[0 speckle(1:end-1)];yd = speckle(1:end);A=repmat(yd(fnd),dm,1);speckle=A(fnd1);% Now give it the same preconditioning as for xi/yispeckle=speckle(num);if rem(length(speckle),2)==1speckle = [speckle; speckle(end)];endspeckle=reshape(speckle,2,li/2);elsespeckle=[speckle;speckle];end% Thin out the points in narrow parts.% This keeps everything when abs(dxi)>2*speckle, and then makes% it increasingly sparse for smaller intervals.dxi=diff(xi);nottoosmall=sum(speckle,1)~=0 & rand(1,li/2)<abs(dxi)./(max(sum(speckle,1),eps));xi=xi(:,nottoosmall);yi=yi(:,nottoosmall);dxi=dxi(nottoosmall);if size(speckle,2)>1, speckle=speckle(:,nottoosmall); end% Now randomly scatter points (if there any left)li=length(dxi);if any(li)xi(1,:)=xi(1,:)+sign(dxi).*(1-rand(1,li).^0.5).*min(speckle(1,:),abs(dxi) );xi(2,:)=xi(2,:)-sign(dxi).*(1-rand(1,li).^0.5).*min(speckle(2,:),abs(dxi) );% Remove the 'zero' specklesif size(speckle,2)>1xi=xi(speckle~=0);yi=yi(speckle~=0);endend
elsexi = [xi; ones(1,li/2)*nan];  % Separate the line segmentsyi = [yi; ones(1,li/2)*nan];
end% Transform back to the original coordinate system
xydatai = [ca -sa;sa ca]*[xi(:)'+u0;(yi(:)'-offset)*step+v0];end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [h,opts,props] = parse_input(h,argin)
% parse & validate input argumentspatchtypes = {'single','cross','speckle','outspeckle','fill','none'};% get base object handle
if ~issupported(h)error('Unsupported graphics handle type.');
end
h = handle(h);% get common property names
pnames = getcommonprops(h);% if style argument is given, convert it to HatchStyle option pair
stylearg = {};
if ~isempty(argin) && ischar(argin{1})tryptypes = validatestring(argin{1},patchtypes);stylearg = {'HatchStyle' ptypes};argin(1) = [];catch% STYL not given, continue onend
end% create inputParser for options
p = inputParser;
p.addParameter('HatchStyle','single');
p.addParameter('HatchAngle',45,@(v)validateattributes(v,{'numeric'},{'scalar','finite','real'}));
p.addParameter('HatchDensity',40,@(v)validateattributes(v,{'numeric'},{'scalar','positive','finite','real'}));
p.addParameter('HatchSpacing',[],@(v)validateattributes(v,{'numeric'},{'scalar','positive','finite','real'}));
p.addParameter('HatchOffset',0,@(v)validateattributes(v,{'numeric'},{'scalar','nonnegative','<',1,'real'}));
p.addParameter('HatchColor','auto',@validatecolor);
p.addParameter('HatchLineStyle','-');
p.addParameter('HatchLineWidth',0.5,@(v)validateattributes(v,{'numeric'},{'scalar','positive','finite','real'}));
p.addParameter('SpeckleWidth',7,@(v)validateattributes(v,{'numeric'},{'scalar','finite','real'}));
p.addParameter('SpeckleDensity',100,@(v)validateattributes(v,{'numeric'},{'scalar','positive','finite','real'}));
p.addParameter('SpeckleMarkerStyle','.');
p.addParameter('SpeckleSize',2,@(v)validateattributes(v,{'numeric'},{'scalar','positive','finite'}));
p.addParameter('SpeckleFillColor','auto',@validatecolor);
p.addParameter('HatchVisible','auto');for n = 1:numel(pnames)p.addParameter(pnames{n},[]);
end
p.parse(stylearg{:},argin{:});rnames = fieldnames(p.Results);
isopt = ~cellfun(@isempty,regexp(rnames,'^(Hatch|Speckle)','once')) | strcmp(rnames,'ContourStyle');
props = struct([]);
for n = 1:numel(rnames)if isopt(n)opts.(rnames{n}) = p.Results.(rnames{n});elseif ~isempty(p.Results.(rnames{n}))props(1).(rnames{n}) = p.Results.(rnames{n});end
endopts.HatchStyle = validatestring(opts.HatchStyle,patchtypes);
if any(strcmp(opts.HatchStyle,{'speckle','outspeckle'}))warning('hatchfill2:PartialSupport','Speckle/outspeckle HatchStyle may not work in the current release of hatchfill2')
end
if strcmpi(opts.HatchStyle,'none') % For backwards compatability:opts.HatchStyle = 'fill';
end
opts.HatchLineStyle = validatestring(opts.HatchLineStyle,{'-','--',':','-.'},mfilename,'HatchLineStyle');if ~isempty(opts.HatchSpacing)warning('HatchSpacing option has been deprecated. Use ''HatchDensity'' option instead.');
end
opts = rmfield(opts,'HatchSpacing');opts.SpeckleMarkerStyle = validatestring(opts.SpeckleMarkerStyle,{'+','o','*','.','x','square','diamond','v','^','>','<','pentagram','hexagram'},'hatchfill2','SpeckleMarkerStyle');
opts.HatchVisible = validatestring(opts.HatchVisible,{'auto','on','off'},mfilename,'HatchVisible');endfunction pnames = getcommonprops(h)
% grab the common property names of the base objectsV = set(h(1));
pnames = fieldnames(V);
if ishghandle(h(1),'hggroup')pnames = union(pnames,getcommonprops(get(h(1),'Children')));
end
for n = 2:numel(h)V = set(h(n));pnames1 = fieldnames(V);if ishghandle(h(n),'hggroup')pnames1 = union(pnames1,getcommonprops(get(h(n),'Children')));endpnames = intersect(pnames,pnames1);
endendfunction validatecolor(val)tryvalidateattributes(val,{'double','single'},{'numel',3,'>=',0,'<=',1});
catchvalidatestring(val,{'auto','y','yellow','m','magenta','c','cyan','r','red',...'g','green','b','blue','w','white','k','black'});
end
end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% axes unit conversion functionsfunction [V,T,islog] = transform_data(ax,V,ref)
% convert vertices data to hatch-ready form
% - if axis is log-scaled, data is converted to their log10 values
% - if 3D (non-zero z), spatially transform data onto the xy-plane. If
%   reference point is given, ref is mapped to the origin. Otherwise, ref
%   is chosen to be the axes midpoint projected onto the patch plane. Along
%   with the data, the axes corner coordinates are also projected onto the
%   patch plane to obtain the projected axes limits.
% - transformed xy-data are then normalized by the projected axes spans.noZ = size(V,2)==2;xl = ax.XLim;
yl = ax.YLim;
zl = ax.ZLim;% log to linear space
islog = strcmp({ax.XScale ax.YScale ax.ZScale},'log');
if islog(1)V(:,1) = log10(V(:,1));xl = log10(xl);if ~isempty(ref)ref(1) = log10(ref(1));end
end
if islog(2)V(:,2) = log10(V(:,2));yl = log10(yl);if ~isempty(ref)ref(2) = log10(ref(2));end
end
if islog(3) && ~noZV(:,3) = log10(V(:,3));zl = log10(zl);if ~isempty(ref)ref(3) = log10(ref(3));end
endif noZV(:,3) = 0;
end% if not given, pick the reference point to be the mid-point of the current
% axes
if isempty(ref)ref = [mean(xl) mean(yl) mean(zl)];
end% normalize the axes so that they span = 1;
Tscale = makehgtform('scale', [1/diff(xl) 1/diff(yl) 1/diff(zl)]);
V(:) = V*Tscale(1:3,1:3);
ref(:) = ref*Tscale(1:3,1:3);% obtain unique vertices
Vq = double(unique(V,'rows')); % find unique points (sorted order)
Nq = size(Vq,1);
if Nq<3 || any(isinf(Vq(:))) || any(isnan(Vq(:))) % not hatchableV = [];T = [];return;
endtry % erros if 2D objectzq = unique(Vq(:,3));
catchV(:,3) = 0;zq = 0;
end
T = eye(4);
if isscalar(zq) % patch is on a xy-planeif zq~=0 % not on the xy-planeT = makehgtform('translate',[0 0 -zq]);end
else% if patch is not on a same xy-plane% use 3 points likely well separatedidx = round((0:2)/2*(Nq-1))+1;% find unit normal vector of the patch planenorm = cross(Vq(idx(1),:)-Vq(idx(3),:),Vq(idx(2),:)-Vq(idx(3),:)); % normal vectornorm(:) = norm/sqrt(sum(norm.^2));% define the spatial rotationtheta = acos(norm(3));if theta>pi/2, theta = theta-pi; endu = [norm(2) -norm(1) 0];Trot = makehgtform('axisrotate',u,theta);% project the reference point onto the planeP = norm.'*norm;ref_proj = ref*(eye(3) - P) + Vq(1,:)*P;if norm(3)T = makehgtform('translate', -ref_proj); % user specified reference point or -d/norm(3) for z-crossingend% apply the rotation nowT(:) = Trot*T;% find the axes limits on the transformed space%    [Xlims,Ylims,Zlims] = ndgrid(xl,yl,zl);%    Vlims = [Xlims(:) Ylims(:) Zlims(:)];%    Vlims_proj = [Vlims ones(8,1)]*T';%    lims_proj = [min(Vlims_proj(:,[1 2]),[],1);max(Vlims_proj(:,[1 2]),[],1)];%    xl = lims_proj(:,1)';%    yl = lims_proj(:,2)';
end% perform the transformation
V(:,4) = 1;
V = V*T';
V(:,[3 4]) = [];T(:) = T*Tscale;endfunction V = revert_data(V,T,islog)N = size(V,1);
V = [V zeros(N,1) ones(N,1)]/T';
V(:,end) = [];% log to linear space
if islog(1)V(:,1) = 10.^(V(:,1));
end
if islog(2)V(:,2) = 10.^(V(:,2));
end
if islog(3)V(:,3) = 10.^(V(:,3));
endend

legendflex.m函数

function varargout = legendflex(varargin)
%LEGENDFLEX Creates a more flexible legend
%
% legendflex(M, param1, val1, ...)
% legendflex(h, M, param1, val1, ...)
% [legend_h,object_h,plot_h,text_str] = legendflex(...)
%
% This offers a more flexible version of the legend command.  It offers a
% different method of positioning the legend, as well as options to:
%
%   - organize legend text and symbols in a grid with a specified number of
%     rows and/or columns
%   - rescale the horizontal space used by each legend symbol
%   - create multiple legends for the same axis
%   - add a title to the legend within the legend box
%
% Unlike in the default legend command, where the legend is positioned
% relative to the labeled objects' parent axis according to one of 16
% location strings, this function positions the legend based on two anchor
% points (one on either the figure or a child object of a figure, and one
% on the legend itself) and a buffer (or offset) between these two anchor
% points. The anchor points refer to the corners and centers of each
% side of the box surrounding the reference object and the legend itself;
% they can be refered to either as numbers (1-8, clockwise from northwest
% corner) or strings ('nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w').  The
% position of the legend is determined by these two points and the distance
% between them, defined in the 'buffer' variable, which by default is
% measured in pixels.  So the combination of
%
%  (..., 'ref', gca, 'anchor', [3 3], 'buffer', [-10 -10])
%
% means that you want the northeast corner of the current axis to be
% aligned with the northeast corner of the legend, but with the legend
% shifted 10 pixels to the left and down.
%
% This method of positioning can be particularly useful when labeling a
% figure that includes many subplots that share a common color scheme,
% where the "best" location for a legend is not necessarily within the
% bounds of an axis.  Unlike the legend command, the axes in the figure are
% never resized (and it is up to the user to check that the legend fits on
% the figure in the specified location).  In addition to being easier than
% manually positioning a legend, this function updates the legend location
% when the figure is resized, preserving the desired alignment.  The
% following anchor/buffer combinations, when used with the default
% reference and a buffer unit of pixels, approximately replicate the
% typical legend locations:
%
% Specifier              Anchor    Buffer
%
% north                  [2 2]     [  0 -10]
% south                  [6 6]     [  0  10]
% east                   [4 4]     [-10   0]
% west                   [8 8]     [ 10   0]
% northeast              [3 3]     [-10 -10]
% northwest              [1 1]     [ 10 -10]
% southeast              [5 5]     [-10  10]
% southwest              [7 7]     [ 10  10]
% northoutside*          [2 6]     [  0  10]
% southoutside*          [6 2]     [  0 -10]
% eastoutside*           [3 8]     [ 10   0]
% westoutside*           [8 3]     [-10   0]
% northeastoutside*      [3 1]     [ 10   0]
% northwestoutside*      [1 3]     [-10   0]
% southeastoutside*      [5 7]     [ 10   0]
% southwestoutside*      [7 5]     [-10   0]  *placed outside axis rather
%                                              than resizing plot box
%
% This function should support all types of plot objects.
%
% Updates to labeled line and patch properties should be reflected in the
% legend.  In pre-R2014b versions of Matlab (those that use the old
% non-object graphics handles), properties of more complex legend labels,
% such as contours, quivers, bars, etc.) will also be synced to the legend;
% however, at this time, the code doesn't update properties for anything
% other than lines and patches in R2014b+ (haven't found a good way to
% listen for changes to the properties of the other graphics object types).
%
% A note on resizing: This function assigns a resize function to the parent
% figure to maintain the position of the legend (in terms of anchor
% location and buffer) as the figure size changes.  If you manually resize
% the legend, this function will respect changes to height, width, and
% units (though I don't recommend changing the units to 'normalized', as
% this can cause the text and symbols to overflow the legend box on
% resize).  It will not respect manual repositioning when resizing, since
% it assumes you want to maintain the anchor/buffer prescription used to
% create it.  Overall, I've tried to make this resize as unobtrusive as
% possible; if your figure already has a resize function at the time you
% apply it, that behavior is inherited, with the legend-resize called
% afterward.  If you plan to further modify the figure's resize function
% post-legendflex and want to maintain repositioning of the legends,
% retrieve the resize function via hfun = get(hfig, 'ResizeFcn'), pass it
% to the new resize function, and invoke it via feval(oldfun, h, ed), where
% h and ed are the default variables passed by a callback function.
%
% Input variables:
%
%   M:          cell array of strings, labels for legend
%
%   h:          handle of axis or handle(s) of object(s) to be labeled.  If
%               this is an axis handle, all children of the axis will be
%               included in the legend.  If not included, current axis is
%               used.
%
% Optional input variables (passed as parameter/value pairs): [default]
%
%   ncol:       number of columns, or 0 to indicate as many as necessary
%               given the # of labeled objects [1 if nrow is 0, 0
%               otherwise]
%
%   nrow:       number of rows, or 0 to indicate as many as necessary
%               given the # of labeled objects [0]
%
%   ref:        handle of object used to position the legend. This can be
%               either a figure or a child object of a figure (and does not
%               need to relate in any way to the objects being labeled).
%               If not included, the reference will be to the axis that a
%               normal legend would be associated with (usually the parent
%               axis of the labeled objects, unless objects from multiple
%               axes are passed, in which case it's the parent object of
%               the first labeled object).
%
%   anchor:     1 x 2 array specifying which points of the reference object
%               and new legend, respectively, to anchor to each other.
%               Anchor points can be described using either numbers (in a 1
%               x 2 double array) or directional strings (in a 1 x 2 cell
%               array) as follows:
%               1:  'nw'    upper left corner
%               2:  'n'     center of top edge
%               3:  'ne'    upper right corner
%               4:  'e'     center of right edge
%               5:  'se'    bottom right corner
%               6:  's'     center of bottom edge
%               7:  'sw'    bottom left corner
%               8:  'w'     center of left edge
%
%               [[3 3], i.e. {'ne' 'ne'}]
%
%   buffer:     1 x 2 array of horizontal and vertical distance,
%               respectively, from the reference anchor point to the legend
%               anchor point. Distance is measured in units specified by
%               bufferunit. [[-10 -10]]
%
%   bufferunit: unit for buffer distance.  Note that this property only
%               affects the units used to position the legend, not the
%               units for the legend itself (which is always a fixed size,
%               based on the space needed to encapsulate the specified
%               symbols and text).  The 'normalized' units are normalized
%               to size of the figure. ['pixels']
%
%   box:        'on' or 'off', specifies whether to enclose legend objects
%               in a box ['on']
%
%   xscale:     scalar value indicating scale factor to apply to the width
%               required by each symbol, relative to the size used by
%               legend. For example, 0.5 will shorten the lines/patches by
%               half. [1]
%
%   title:      A title string to be added inside the legend box, centered,
%               above all legend entries.  This can be either a string or a
%               cell array of strings; the latter will produce a multi-line
%               title. If empty, no title is added.  ['']
%
%   padding:    1 x 3 array, pixel spacing added to beginning of each
%               column (before symbol), between symbol and text, and after
%               text, respectively.  Usually, the default provides the
%               spacing typical of a regular legend, but occassionally the
%               extent properties wrap a little too close to text, making
%               things look crowded; in these cases you can try unsquishing
%               (or squishing, via use of negative values) things via this
%               parameter. [2 1 1]
%
%   nolisten:   logical scalar.  If true, don't add the event listeners.
%               The event listeners update the legend objects when you
%               change a property of the labeled objects (such as line
%               style, color, etc.).  However, the updating requires the
%               legend to be redrawn, which can really slow things down,
%               especially if you're labelling lots of objects that get
%               changed together (if you change the line width of 100
%               labeled lines, the legend gets redrawn 100 times).  In more
%               recent releases, this also occurs when printing to file, so
%               I recommend setting this to true if you plan to print a
%               legend with a large number of labeled objects.  The legend
%               will still be redrawn on figure resize regardless of the
%               value of this parameter. [false]
%
%   In addition to these legendflex-specific parameters, this function will
%   accept any parameter accepted by the original legend function (e.g.
%   font properties) except 'location', 'boxon', 'boxoff', or 'hide'.
%
% Output variables:
%
%   legend_h:   handle of the legend axis.  It is not linked to an axis or
%               graphics objects in the same way as a Matlab legend.
%               However, on figure resize, all properties of the legend
%               objects are checked for changes, so adjusting the figure
%               size can re-link the legend to the labeled objects after
%               you have made changes to those objects.
%
%   object_h:   handles of the line, patch, and text graphics objects
%               created in the legend
%
%   plot_h:     handles of the lines and other objects labeled in this
%               legend
%
%   text_str:   cell array of the text strings used in the legend
%
%
% Example:
%
% % Replicating an example from legend.m:
%
% figure;
% b = bar(rand(10,5),'stacked'); colormap(summer); hold on
% x = plot(1:10,5*rand(10,1),'marker','square','markersize',12,...
%          'markeredgecolor','y','markerfacecolor',[.6 0 .6],...
%          'linestyle','-','color','r','linewidth',2); hold off
% lbl = {'Carrots','Peas','Peppers','Green Beans','Cucumbers','Eggplant'};
%
% % Rather than covering up data or resizing the axis, let's squeeze the
% % legend into the margin at the top of the figure;
%
% legendflex([b,x], lbl, 'ref', gcf, ...
%                        'anchor', {'n','n'}, ...
%                        'buffer',[0 0], ...
%                        'nrow',2, ...
%                        'fontsize',8);% Copyright 2011-2014 Kelly Kearney% Detemine whether HG2 is in usehg2flag = ~verLessThan('matlab', '8.4.0');
r2016aflag = ~verLessThan('matlab', '9.0.0');
r2013bflag = ~verLessThan('matlab', '8.2.0');%-------------------
% Parse input
%-------------------
%
% allinput = varargin; % Save for callback later
%
% islegin = false(size(varargin));% First inputs must be either:
% (M, ...)
% (h, M, ...)narginchk(1,Inf);% Split input into the variables that will be passed to legend (handles and
% labels) and everything elsehandlepassed = all(ishandle(varargin{1})); % for HG1/HG2 iscellstr = @(x) cellfun(@(y) ischar(y), x); % For now...
% iscellstr = @(x) cellfun(...
%     @(y) ischar(y) || (iscell(y) && all(cellfun(@ischar,y))), x); % for multi-line?if handlepassedlegin = varargin(1:2);if ~iscell(legin{2}) || ~all(iscellstr(legin{2}))error('Legend labels must be a cell array of strings');endpv = varargin(3:end);
elselegin = varargin(1);if ~iscell(legin{1}) || ~all(iscellstr(legin{1}))if isnumeric(legin{1})error('Unable to parse input 1; check that handle(s) exist');elseerror('Legend labels must be a cell array of strings');endendpv = varargin(2:end);
end% Parse my optional propertiesif hg2flagdefref = gobjects(0);
elsedefref = NaN;
endif r2013bflagaddParamMethod = 'addParameter';
elseaddParamMethod = 'addParamValue';
endp = inputParser;
p.(addParamMethod)('xscale',     1,         @(x) validateattributes(x, {'numeric'}, {'nonnegative','scalar'}));
p.(addParamMethod)('ncol',       0,         @(x) validateattributes(x, {'numeric'}, {'scalar', 'integer'}));
p.(addParamMethod)('nrow',       0,         @(x) validateattributes(x, {'numeric'}, {'scalar', 'integer'}));
p.(addParamMethod)('ref',        defref,    @(x) validateattributes(x, {'numeric','handle'}, {'scalar'}));
p.(addParamMethod)('anchor',     [3 3],     @(x) validateattributes(x, {'numeric','cell'}, {'size', [1 2]}));
p.(addParamMethod)('buffer',     [-10 -10], @(x) validateattributes(x, {'numeric'}, {'size', [1 2]}));
p.(addParamMethod)('bufferunit', 'pixels',  @(x) validateattributes(x, {'char'}, {}));
p.(addParamMethod)('box',        'on',      @(x) validateattributes(x, {'char'}, {}));
p.(addParamMethod)('title',      '',        @(x) validateattributes(x, {'char','cell'}, {}));
p.(addParamMethod)('padding',    [2 1 1],   @(x) validateattributes(x, {'numeric'}, {'size', [1 3]})); % 'nonnegative'
p.(addParamMethod)('nolisten',   false,     @(x) validateattributes(x, {'logical'}, {'scalar'}));
p.KeepUnmatched = true;p.parse(pv{:});
Opt = p.Results;% Any parameters that don't match mine are assumed to be a legend property.
%  If not, legend will handle the error when I call it.Extra = p.Unmatched;
extra = [fieldnames(Extra) struct2cell(Extra)];
extra = extra';% Validate that units and box inputs are correctvalidatestring(Opt.bufferunit, {'pixels','normalized','inches','centimeters','points','characters'}, 'legendflex', 'bufferunit');
validatestring(Opt.box, {'on', 'off'}, 'legendflex', 'box');% Translate anchor strings to numbers, if necessaryif iscell(Opt.anchor)[blah, Opt.anchor] = ismember(Opt.anchor, {'nw','n','ne','e','se','s','sw','w'});if ~all(blah)error('Anchor must be 1 x 2 cell array of strings: n, e, s, w, ne, nw, se, sw');end
elsevalidateattributes(Opt.anchor, {'numeric'}, {'integer', '<=', 8}, 'legendflex', 'anchor');
end% Create a temporary legend to get all the objectsS = warning('off', 'MATLAB:legend:PlotEmpty');
if r2016aflag% The new legend objects are pretty opaque... even diving into the % undocumented properties, I haven't been able to find the handles of % the legend sub-components (lines, text, etc).  So I need to stick to % the legacy version, which creates an axis object rather than legend % object. Legacy version has bug in text properties parsing, though, so % need to work around that too: use the new-style legend object to get% proper text properties, then use those to alter the buggy old-style% legend.tmp = legend(legin{:}, extra{:}, 'location', 'northeast');textProps = {'FontAngle','FontName','FontSize','FontUnits','FontWeight','Interpreter'};tprop = get(tmp, textProps);delete(tmp);wtmp = warning('off', 'MATLAB:handle_graphics:exceptions:SceneNode'); % silence Latex interpreter thing[h.leg, h.obj, h.labeledobj, h.textstr] = legend(legin{:}, extra{:}, 'location', 'northeast');warning(wtmp);nobj = length(h.labeledobj);for it = 1:length(textProps)set(h.obj(1:nobj), textProps{it}, tprop{it});end
else[h.leg, h.obj, h.labeledobj, h.textstr] = legend(legin{:}, extra{:}, 'location', 'northeast');nobj = length(h.labeledobj);
end
warning(S);if nobj == 0warning('Plot empty; no legend created');return
end% There's a bug in R2014b-R2015a that causes rendering issues if a contour
% object is included in a legend and legend is called with more than one
% output. For some reason, the rendering issues disappear only if the
% contour object(s) is listed last in the legend.  So for now, my
% workaround for this is to change the order of the legend labels as
% necessary.  Issue appears to be fixed in 2015b.iscont = strcmp(get(h.labeledobj, 'type'), 'contour');
cbugflag = ~verLessThan('matlab', '8.4.0') && verLessThan('matlab', '8.6.0') && any(iscont);if cbugflagif length(legin) == 1legin = {h.labeledobj legin{1}};enddelete(h.leg);[srt, isrt] = sort(iscont);legin{1} = legin{1}(isrt);legin{2} = legin{2}(isrt);[h.leg, h.obj, h.labeledobj, h.textstr] = legend(legin{:}, extra{:}, 'location', 'northeast');end% # rows and columnsif (Opt.ncol == 0) && (Opt.nrow == 0)Opt.ncol = 1;Opt.nrow = nobj;
elseif (Opt.ncol == 0)Opt.ncol = ceil(nobj./Opt.nrow);
elseif (Opt.nrow == 0)Opt.nrow = ceil(nobj./Opt.ncol);
end
if Opt.ncol*Opt.nrow < nobjerror('Number of legend entries greater than specified grid allows; change ncol and/or nrow');
end% Reference objectif hg2flagif isempty(Opt.ref)if all(ishandle(legin{1}))tmp = ancestor(legin{1}, 'axes');if iscell(tmp)Opt.ref = tmp{1}; elseOpt.ref = tmp(1);endelseOpt.ref = gca;endend
elseif isnan(Opt.ref)tmp = get(h.leg, 'UserData');Opt.ref = tmp.PlotHandle; end
end
if ~ishandle(Opt.ref)error('Input ref must be a graphics handle');
end% BoxOpt.box = strcmpi('on', Opt.box);% Convert units to getpos abbreviationsunittable = {...'px'  'Pixels''nz'  'Normalized''in'  'Inches''cm'  'Centimeters''pt'  'Points''ch'  'Characters'};
Opt.bufunit = unittable{strcmpi(unittable(:,2),Opt.bufferunit),1};% Check for titleaddtitle = ~isempty(Opt.title);%-------------------
% New placement of
% everything in
% legend
%-------------------% Determine parent figurefigh = ancestor(Opt.ref, 'figure');
currax = get(figh, 'currentaxes'); % Calculate row heightlegpospx = getpos(h.leg, 'px');% rowHeight = legpospx(4)/nobj;
vmarginNm =  0.275/nobj;
vmarginPx = legpospx(4) * vmarginNm;rowHeightNm = (1 - vmarginNm)/nobj;
rowHeight = rowHeightNm .* legpospx(4);% Determine width needed for each text stringif nobj == 1textExtent = get(h.obj(1:nobj), 'Extent');
elsetextExtent = cell2mat(get(h.obj(1:nobj), 'Extent'));
end
textWidthPx  = textExtent(:,3) .* legpospx(3);
textHeightPx = textExtent(:,4) .* legpospx(4);
textWidthNm = textExtent(:,3);% Calculate horizontal space needed for symbolssymbolWidthPx = textExtent(1,1) .* legpospx(3) * Opt.xscale;
symbolWidthNm = textExtent(1,1);% Calculate column width needed for 2px-symbol-1px-text-1pxcolWidth = zeros(Opt.ncol*Opt.nrow,1);
colWidth(1:nobj) = textWidthPx + symbolWidthPx + sum(Opt.padding);
colWidth = reshape(colWidth, Opt.nrow, Opt.ncol);
colWidth = max(colWidth,[],1);% If title is added, figure out how much space it will needif addtitletextProps = {'FontAngle','FontName','FontSize','FontUnits','FontWeight','Interpreter'};textVals = get(h.obj(1), textProps);ttlprops = [textProps; textVals];fpos = getpos(figh, 'px');figtmp = figure('units','pixels','position',[0 0 fpos(3:4)],'visible','off');axes('parent',figtmp,'position',[0 0 1 1],'xlim',[0 fpos(3)],'ylim',[0 fpos(4)]);tmp = text(0,0,Opt.title, ttlprops{:}, 'horiz', 'left', 'vert', 'bottom');ttlex = get(tmp, 'extent');ttlwidth = ceil(ttlex(3)) + 4; % Add a little paddingttlheight = ceil(ttlex(4));if ttlwidth > sum(colWidth)colWidth(end) = colWidth(end) + (ttlwidth-sum(colWidth));endclose(figtmp);
end% Locate bottom left corner of each legend symbol, text box, and titlexsymbnew = [0 cumsum(colWidth(1:end-1))]+Opt.padding(1);
ysymbnew = (rowHeight*Opt.nrow + vmarginPx)-(1:Opt.nrow)*rowHeight;
[xsymbnew, ysymbnew] = meshgrid(xsymbnew, ysymbnew);
xsymbnew = xsymbnew(1:nobj);
ysymbnew = ysymbnew(1:nobj);xtext = xsymbnew + Opt.padding(2) + symbolWidthPx;
ytext = ysymbnew;% + 1;xsymbold = zeros(nobj,1);
ysymbold = 1 - (1/nobj)*(1:nobj);wnewleg = sum(colWidth);
hnewleg = rowHeight*Opt.nrow + vmarginPx;if addtitlexttl = wnewleg/2;yttl = hnewleg;hnewleg = hnewleg + ttlheight;
end% Get legend position in bufferunit and translate to pixelslegpos = positionleg(Opt.ref, wnewleg, hnewleg, Opt.anchor, Opt.buffer, Opt.bufunit);
tmpax = axes('units', Opt.bufferunit, 'position', legpos,'visible','off');
legpos = getpos(tmpax, 'px');
delete(tmpax);%-------------------
% Create legend
%-------------------% Create the legend axishnew.leg = axes('units', 'pixels', ...'position', legpos, ...'xlim', [0 legpos(3)], ...'ylim', [0 legpos(4)], ...'xtick', [], ...'ytick', [], ...'box', 'on', ...'parent', figh);% Copy the text strings to the new legendtextProps = {'FontAngle','FontName','FontSize','FontUnits','FontWeight','Interpreter','HorizontalAlignment','VerticalAlignment'};
textVals = get(h.obj(1:nobj), textProps);if hg2flaghnew.obj = gobjects(size(h.obj));
elsehnew.obj = zeros(size(h.obj));
end
for it = 1:nobjprops = [textProps; textVals(it,:)];hnew.obj(it) = text(xtext(it), ytext(it), h.textstr{it}, props{:}, ...'horizontalalignment', 'left', ...'verticalalignment', 'bottom');
end% Copy the symbols to the new legendnsymbol = length(h.obj) - nobj;for ii = 1:nsymbolif strcmp(get(h.obj(nobj+ii), 'type'), 'hggroup')tag = get(h.obj(nobj+ii),'Tag');if ~isempty(tag)[blah, idx] = ismember(tag,h.textstr);endchld = findall(h.obj(nobj+ii), 'type', 'line', '-or', 'type', 'patch');       for ic = 1:length(chld)xy = get(chld(ic), {'xdata', 'ydata'});xnorm = xy{1}./symbolWidthNm;ynorm = (xy{2}- (1-idx*rowHeightNm))./rowHeightNm;xnew = xnorm * symbolWidthPx + xsymbnew(idx);ynew = ynorm * rowHeight     + ysymbnew(idx);set(chld(ic), 'xdata', xnew, 'ydata', ynew);endhnew.obj(nobj+ii) = copyobj(h.obj(nobj+ii), hnew.leg);else   hnew.obj(nobj+ii) = copyobj(h.obj(nobj+ii), hnew.leg);tag = get(h.obj(nobj+ii),'Tag');if ~isempty(tag) % assumes empty tags indicate repetition of previous tag (true pre-2014b)[blah, idx] = ismember(tag,h.textstr);endxy = get(h.obj(nobj+ii), {'xdata', 'ydata'});xnorm = xy{1}./symbolWidthNm;ynorm = (xy{2}- (1-idx*rowHeightNm))./rowHeightNm;xnew = xnorm * symbolWidthPx + xsymbnew(idx);ynew = ynorm * rowHeight     + ysymbnew(idx);set(hnew.obj(nobj+ii), 'xdata', xnew, 'ydata', ynew);endend% Add titleif addtitletext(xttl, yttl, Opt.title, ttlprops{:}, 'horiz', 'center', 'vert', 'bottom');
end% Add box or hide axisif Opt.boxset(hnew.leg, 'box', 'on');
elseif hg2flagset(hnew.leg, 'box', 'off', 'color', 'none', 'xcolor', 'none', 'ycolor', 'none');elseset(hnew.leg, 'visible', 'off');end
end% Delete the temporary legenddelete(h.leg);% Return focus to previously-current axisset(figh, 'currentaxes', currax);
drawnow; % Not sure why this is necessary for the currentaxes to take effect, but it is% Fix for vertical-alignment issue: This solution still isn't perfect, but
% it seems to help for most Interpreter-none and Interpreter-latex cases.
% The TeX interpreter still places sub- and superscripts too high/low... no
% robust fix found for that yet.
%
% TODO: need to add proper calcs for when title included
%
% Thanks to S�ren Enemark for this suggestion.if ~addtitletry % TODO: Crashing on some edge casestextobj = hnew.obj(1:nobj);yheight = get(hnew.leg, 'ylim');yheight = yheight(2);ylo = get(textobj(Opt.nrow), 'extent');ylo = ylo(2);yhi = get(textobj(1), 'extent');yhi = sum(yhi([2 4]));dy = yheight/2 - 0.5*(ylo + yhi);for ii = 1:length(textobj)pos = get(textobj(ii), 'position');set(textobj(ii), 'position', pos + [0 dy 0]);endend
end%-------------------
% Callbacks and
% listeners
%-------------------% Save some relevant variables in the new legend axis's application dataLf.ref        = Opt.ref;
Lf.w          = wnewleg;
Lf.h          = hnewleg;
Lf.anchor     = Opt.anchor;
Lf.buffer     = Opt.buffer;
Lf.bufunit    = Opt.bufunit;
Lf.bufferunit = Opt.bufferunit;
Lf.plotobj    = h.labeledobj;
Lf.legobj     = hnew.obj;setappdata(hnew.leg, 'legflex', Lf);% Resize listenersaddlistener(hnew.leg, 'Position', 'PostSet', @(src,evt) updatelegappdata(src,evt,hnew.leg));
if hg2flag && strcmp(Lf.ref.Type, 'figure')addlistener(Lf.ref, 'SizeChanged', @(src,evt) updatelegpos(src,evt,hnew.leg));
elseaddlistener(Lf.ref, 'Position', 'PostSet', @(src,evt) updatelegpos(src,evt,hnew.leg));
end
rsz = get(figh, 'ResizeFcn');
if isempty(rsz) % No previous resize functionset(figh, 'ResizeFcn', @updatelegfigresize);
else if ~iscell(rsz)rsz = {rsz};endhasprev = cellfun(@(x) isequal(x, @updatelegfigresize), rsz);if ~hasprevrsz = {rsz{:} @updatelegfigresize};set(figh, 'ResizeFcn', {@wrapper, rsz});end
endif ~Opt.nolisten% Run the resync function if anything changes with the labeled objectsobjwatch = findall(h.labeledobj, 'type', 'line', '-or', 'type', 'patch');for ii = 1:length(objwatch)switch lower(get(objwatch(ii), 'type'))case 'line'triggerprops = {'Color','LineStyle','LineWidth','Marker','MarkerSize','MarkerEdgeColor','MarkerFaceColor'};addlistener(objwatch(ii), triggerprops, 'PostSet', @(h,ed) resyncprops(h,ed,hnew.leg));case 'patch'triggerprops = {'CData','CDataMapping','EdgeAlpha','EdgeColor','FaceAlpha','FaceColor','LineStyle','LineWidth','Marker','MarkerEdgeColor','MarkerFaceColor','MarkerSize'};addlistener(objwatch(ii), triggerprops, 'PostSet', @(h,ed) resyncprops(h,ed,hnew.leg));endendend%-------------------
% Output
%-------------------out = {hnew.leg, hnew.obj, h.labeledobj, h.textstr};
varargout = out(1:nargout);%***** Subfunctions *****%------------------------
% Position new legend
%------------------------function legpos = positionleg(href, w, h, anchor, buffer, bufunit)
% ap: position vector for reference object
% lp: position vector for legendif strcmp(get(href, 'type'), 'figure')tmp = axes('parent', href,'position', [0 0 1 1],'visible','off');pos = getpos(tmp, bufunit);delete(tmp);
elsepos = getpos(href, bufunit);
endhtmp = axes('units', 'pixels', 'position', [0 0 w h], 'visible','off');
lpos = getpos(htmp, bufunit);
delete(htmp);
w = lpos(3);
h = lpos(4);% Find anchor locations on reference objectrefxy = [...pos(1)          pos(2)+pos(4)pos(1)+pos(3)/2 pos(2)+pos(4)pos(1)+pos(3)   pos(2)+pos(4)pos(1)+pos(3)   pos(2)+pos(4)/2pos(1)+pos(3)   pos(2)pos(1)+pos(3)/2 pos(2)pos(1)          pos(2)pos(1)          pos(2)+pos(4)/2];% How bottom left relates to each anchor pointshift = [...0       -h-w/2    -h-w      -h-w      -h/2-w      0-w/2    00       00       -h/2];% Legend locationcorner = refxy(anchor(1),:) + buffer + shift(anchor(2),:);
legpos = [corner w h];%------------------------
% Listener functions
%------------------------% If user manually resizes the legend, update the app datafunction updatelegappdata(src, evt, legax)
if ishandle(legax)Lf = getappdata(legax, 'legflex');pos = getpos(legax, 'px');Lf.w = pos(3);Lf.h = pos(4);setappdata(legax, 'legflex', Lf);
end
% If reference object moves or resizes, reposition the legend appropriatelyfunction updatelegpos(src, evt, legax)
if ishandle(legax) Lf = getappdata(legax, 'legflex');legpos = positionleg(Lf.ref, Lf.w, Lf.h, Lf.anchor, Lf.buffer, Lf.bufunit);set(legax, 'Units', Lf.bufferunit, 'Position', legpos);
end% Since figure resize can change axis size without actually triggering a
% listener, force thisfunction updatelegfigresize(src, evt)allax = findall(src, 'type', 'axes');
for ii = 1:length(allax)isleg = ~isempty(getappdata(allax(ii), 'legflex'));if ~islegpos = get(allax(ii), 'Position');set(allax(ii), 'Position', pos); % No change, just trigger PostSetend
end% If plotted object changes, resync with legendfunction resyncprops(src, evt, legax)if ishandle(legax) % In case it's been deletedLf = getappdata(legax, 'legflex');str = cellstr(num2str((1:length(Lf.plotobj))'));[htmp.leg, htmp.obj, htmp.labeledobj, htmp.textstr] = legend(Lf.plotobj, str);objtype = get(Lf.legobj, 'type');isline = strcmp(objtype, 'line');ispatch = strcmp(objtype, 'patch');ishg = strcmp(objtype, 'hggroup');hgidx = find(ishg);lobj = [Lf.legobj(isline) htmp.obj(isline)];pobj = [Lf.legobj(ispatch) htmp.obj(ispatch)];if ~isempty(hgidx)for ih = hgidxchldln1 = findall(Lf.legobj(ih), 'type', 'line');chldln2 = findall(htmp.obj(ih), 'type', 'line'); lobj = [lobj; [chldln1 chldln2]];chldpa1 = findall(Lf.legobj(ih), 'type', 'patch');chldpa2 = findall(htmp.obj(ih), 'type', 'patch'); pobj = [pobj; [chldpa1 chldpa2]];endendlprops = {'color','linestyle','linewidth','marker','markersize','markeredgecolor','markerfacecolor'};for il = 1:size(lobj,1)lvals = get(lobj(il,2), lprops);pv = [lprops; lvals];set(lobj(il,1), pv{:});endpprops = {'cdata','cdatamapping','edgealpha','edgecolor','facealpha','facecolor','linestyle','linewidth','marker','markeredgecolor','markerfacecolor','markersize'};for ip = 1:size(pobj,1)pvals = get(pobj(ip,2), pprops);pv = [pprops; pvals];set(pobj(ip,1), pv{:});endcmap = colormap(htmp.leg);colormap(legax, cmap);delete(htmp.leg);
end% Wrapper to add multiple callback functions to resizefunction wrapper(ObjH, EventData, fcnList)
for ii = 1:length(fcnList)feval(fcnList{ii}, ObjH, EventData);
end

getpos.m

function [pos,unit]=getpos(h,fmt,href,opt)
% GETPOS Get graphics object position in a flexible way.
%   GETPOS(H,FMT) gets the position property of graphics object
%   with handle H, according to FMT that can be expressed using different
%   units. H must have a "Position" property.
%
%   FMT is a char array containing four "%2c" strings separated by colon or
%   space. The two characters specify the unit as :
%
%           px  for Pixels
%           nz  for Normalized
%           in  for Inches
%           cm  for Centimeters
%           pt  for Points
%           ch  for Characters
%
%   If FMT is only one format string from the above list, all returned values are
%   expressed using this unit.
%
%   Any string value of FMT can be replaced by a single '#' to not retrieve the
%   corresponding value. The returned value is NaN except if the optional last
%   argument OPT is set to "compact" in GETPOS(H,FMT,[HREF],OPT).
%
%   Note that GETPOS(H) works as get(H,'Position') and return the position
%   vector in the current unit of the graphics object H.
%
%   GETPOS(H,FMT,HREF,['compact']) gets the position of the graphics object H according
%   to FMT, but using the position of the graphics object HREF as reference instead
%   of the parent of H. HREF must be a valid handle and must have a "Position"
%   property (except for the Root object). Returned values may be negative or 0.
%
%   [POS,UNIT]=GETPOS(H,...) returns an additional output argument UNIT that
%   contained the unit list of the output vector position POS. It may be safer
%   when different units are used.
%
%   See also SETPOS, SET, GET.%   Author: J�r�me Briot, Matlab 6.1.0.450 (R12.1)
%   Contact: dutmatlab@yahoo.fr
%   Revision: 1.0 (12-Feb-2007)
%             1.1 (14-Feb-2007) Third input argument HREF added.
%                               Minor corrections in the help section.
%             1.2 (21-Feb-2007) Bug fixed if HREF is the Root object
%                               Examples removed from the help section
%   Comments:
%% Check the number of input argumentsnarginchk(1,4);% Check if H is a graphics object handle
if ~ishandle(h)error('First argument must be a graphic object handle');
end% Store the current unit of the graphics object H
current_unit=get(h,'units');% Init variables
unit={current_unit current_unit current_unit current_unit};
pos=[nan nan nan nan];% If FMT input argument is not specified, works as GET(H,'Position')
if nargin==1pos=get(h,'position');return
end% Check if FMT is a char string
if ~ischar(fmt)error('Second argument must be a string in GETPOS(H,FMT)')
end  if nargin==2 % GETPOS(H,FMT)href=get(h,'parent');opt='full';elseif nargin==3if ishandle(href) % GETPOS(H,FMT,HREF)opt='full';elseif strcmpi(href,'compact') % GETPOS(H,FMT,"compact")href=get(h,'parent');opt='compact';else % GETPOS(H,FMT,???)error('Wrong third argument in GETPOS(H,FMT,???). Must be a valid handle or "compact"');endelseif nargin==4 % GETPOS(H,FMT,HREF,OPT)if ~ishandle(href) error('Third argument must be a valid handle in GETPOS(H,FMT,HREF,OPT)');endif ~strcmpi(opt,'compact') error('Last argument must be "compact" in GETPOS(H,FMT,HREF,OPT)'); endendflag_href=0;
% Don't use HREF position if it is the parent of H
if href~=get(h,'parent')href=h;flag_href=1;
end% Store the current unit of the reference object HREF
current_ref_unit=get(href,'units');% Extract 4 char strings from FMT
M=strread(fmt,'%s','delimiter',' ,');% Only one FMT requested for output
if numel(M)==1[M{2:4}]=deal(M{1});
end% List available units
available_units={'inches' 'centimeters' 'normalized' 'points' 'pixels' 'characters'};% Decode elements of FMT
for n=1:numel(M) % If FMT(n) is not a "#"if ~strcmp(M{n},'#')% Check if the units paramter is valididx=strcmpi(M{n},{'in' 'cm' 'nz' 'pt' 'px' 'ch'});if ~any(idx)error('Units must be one of "in", "cm", "nz", "pt", "px" or "ch"')endunit{n}=available_units{idx}; % Set the units to one from the list endend% Get position of H using decoded FMT
for n=1:numel(M)    % If FMT(n) is not a "#" => get the valueif ~strcmp(M{n},'#')% Modify the "Units" property of H set(h,'units',unit{n});% Modify the "Units" property of HREFset(href,'units',unit{n});% Get the current "Position" vector of Htemp=get(h,'position');% Get the current "Position" vector of HREFif strcmp(get(href, 'type'), 'root') % HREF is the Root object (no 'Position' property)temp_href=get(href,'screensize'); %%% Should be safe here !else temp_href=get(href,'position');end% Get and store the specified field from the "Position" vector% If HREF is specified and is not the parent of H, flag_href=1 else flag_href=0pos(n)=temp(n)-temp_href(n)*flag_href;endend% Check for compact output format
if strcmpi(opt,'compact')pos(isnan(pos))=[];
end% Restore the unit of the graphics object H
set(h,'units',current_unit);
% Restore the unit of the reference object HREF
set(href,'units',current_ref_unit);

02、编写柱状图代码

clc;
clear;
%If you want to adjust the pattern to 6 bar such as " applyhatch(gcf,'.-+/|x');",
%try to type this "applyhatch(gcf,'.-++/||xx');" instedly.
%So you can avoid the duplicated pattern at least, even order problem is still not solved.
data=[100, 200, 900, 1400, 788;111, 222, 333, 444, 555];%三列的柱状图,分为了两种,具体见图
X = [1,2];GO = bar(X,data,1,'EdgeColor','k','LineWidth',1);hatchfill2(GO(1),'cross','HatchAngle',45,'HatchDensity',40,'HatchColor','k');
hatchfill2(GO(2),'single','HatchAngle',45,'HatchDensity',40,'HatchColor','k');
hatchfill2(GO(3),'single','HatchAngle',0,'HatchDensity',40,'HatchColor','k');
hatchfill2(GO(4),'single','HatchAngle',-45,'HatchDensity',40,'HatchColor','k');
hatchfill2(GO(5),'cross','HatchAngle',-60,'HatchDensity',30,'HatchColor','k');GO(1).FaceColor = [0.000, 0.447, 0.741];
GO(2).FaceColor = [0.850, 0.325, 0.098];
GO(3).FaceColor = [0.929, 0.694, 0.125];
GO(4).FaceColor = [0.494, 0.184, 0.556];
GO(5).FaceColor = [0.466, 0.674, 0.188];% Draw the legend
legendData = {'Legend 1','Legend 2','Legend 3', 'Legend 4', 'Legend 5'};
[legend_h, object_h, plot_h, text_str] = legendflex(GO, legendData, 'Padding', [2, 2, 10], 'FontSize', 11, 'Location', 'NorthEast');
% object_h(1) is the first bar's text
% object_h(2) is the second bar's text
% object_h(3) is the first bar's patch
% object_h(4) is the second bar's patch
%
% Set the two patches within the legend
hatchfill2(object_h(6), 'cross', 'HatchAngle', 45, 'HatchDensity', 40, 'HatchColor', 'k');
hatchfill2(object_h(7), 'single', 'HatchAngle', 45, 'HatchDensity', 40, 'HatchColor', 'k');
hatchfill2(object_h(8), 'single', 'HatchAngle', 0, 'HatchDensity', 40, 'HatchColor', 'k');
hatchfill2(object_h(9), 'single', 'HatchAngle', -45, 'HatchDensity', 40, 'HatchColor', 'k');
hatchfill2(object_h(10), 'cross', 'HatchAngle', -60, 'HatchDensity', 30, 'HatchColor', 'k');
% Some extra formatting to make it pretty :)
set(gca, 'FontSize', 11);
set(gca, 'XMinorTick','on', 'XMinorGrid','on', 'YMinorTick','on', 'YMinorGrid','on');
% xlim([0.5, 2.5]);
ylim([0, 1500]);% hTitle = title('Texture filled bar chart');
% hXLabel = xlabel('Samples');
hYLabel = ylabel('AAAA');

大概效果如下:

至此就可以优雅的在Matlab的柱状图里填充线条啦,当然也可以用Excel来进行画图,更方便~

Matlab柱状图填充线条【研究一天终于弄明白了】相关推荐

  1. ThreadLocal原理详解--终于弄明白了ThreadLocal

    ThreadLocal原理详解 在我看到ThreadLocal这个关键字的时候我是懵逼的,我觉得我需要弄明白,于是,我就利用搜索引擎疯狂查找,试图找到相关的解答,但是结果不尽人意. 首先说一下我的理解 ...

  2. 终于弄明白 i = i++和 i = ++i 的区别了!

    写在前面:前些天看完了JVM的内存结构,自以为自己是懂了,心里想想不就是分线程共享和线程私有嘛,然后又怎么怎么分怎么怎么的嘛- 直到遇到了这道题目.说句实话,曾经自己做这种运算题目,完全是靠脑子空想, ...

  3. 终于弄明白 i = i++和 i = ++i 了

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:腾讯推出高性能 RPC 开发框架 个人原创100W+访问量博客:点击前往,查看更多 来源:https://url ...

  4. 终于弄明白Framework 3.5为什么在IIS的ASP.NET选项找不到?

    本人现在正在研究VS2008,发现VS2008带的Framework 3.5,于是我去IIS ASP.NET里面看看是不是有那个选项. 发现没有.于是乎就想到这是脚本没有映射.用以前注册Framewo ...

  5. 终于弄明白了 Singleton,Transient,Scoped 的作用域是如何实现的

    一:背景 1. 讲故事 前几天有位朋友让我有时间分析一下 aspnetcore 中为什么向 ServiceCollection 中注入的 Class 可以做到 Singleton,Transient, ...

  6. 各层作用_终于弄明白了 Singleton,Transient,Scoped 的作用域是如何实现的

    一:背景 1. 讲故事 前几天有位朋友让我有时间分析一下 aspnetcore 中为什么向 ServiceCollection 中注入的 Class 可以做到 Singleton,Transient, ...

  7. 车速表 html 效果,车速表速度显示的问题,终于弄明白了!

    一直以来对车速表速度显示总是心存疑惑,因为车上显示的速度GPS显示的总有一定的误差,看了一些帖子总结,终于明白了. 首先(别人的帖子): 测速仪 根据中华人民共国国家标准(GB/T21255- ...

  8. jsp 使用base标签 没有作用_终于弄明白衣服上,使用前请移除的标签到底是什么,起什么作用...

    点击上方"机械设计一点通"关注我们,每天学习一个机械设计相关知识点 发现买的T恤上,连在衣服上有个标签,上面写着使用前请移除.里面有个一硬条状物体,不知道是什么,很好奇,便把它拆开 ...

  9. dfs、bfs的终于弄明白了

    ????????关注后回复 "进群" ,拉你进程序员交流群???????? 作者丨大赛 来源丨bigsai 前言 你问一个人听过哪些算法,那么深度优先搜索(dfs)和宽度优先搜索( ...

最新文章

  1. 小白学习python好还是java好_小白应该学Python还是Java?
  2. JDK1.8源码(三)——java.lang.String 类
  3. MATLAB从入门到精通-如何用matlab来提取txt文本中的实验数据
  4. 【OpenCV入门学习笔记1】:Mat对象的指针操作和掩膜操作
  5. SSM+mybatis单元测试
  6. 分析FLV文件分析和解析器的开源代码
  7. java 线程执行结束_Java_如何等待子线程执行结束
  8. ceph升级到10.2.3 版本启动服务报错:Unknown lvalue 'TasksMax' in section 'Service'
  9. python+Appium 滑动界面操作遇到取的元素宽度为负数
  10. windows下打开jenkins
  11. 【2018宁夏邀请赛 L】Continuous Intervals【线段树】
  12. Python Roberts算子、Sobel算子——举例说明 ^_^
  13. C++(一)#pragma once用法
  14. mysql学习笔记(八)事务管理
  15. BUUCTF(web刷题记录一)
  16. 深度学习-BP曲线拟合(预测)
  17. android studio 更换darcula主题中的字体颜色以及常用主题
  18. BC26 TCP透传
  19. P-Link ARM Cortex-M脱机编程器开源前的一些准备工作----第四章 几个重要的结构体介绍
  20. 泛微OA发送内部邮件教程【E9版本】

热门文章

  1. Linux C/C++编程之(十九)进程组守护进程
  2. I·See·Right 遇见kafka的ISR
  3. LDR6328支持不同电压输出,TYPE-C转DC/surface快充线方案
  4. c语言200例 016 水池注水问题
  5. 代码评审(Code Review)
  6. 过去的一年——考研和校招
  7. 盲盒的前身是什么,为什么越来越多的人愿意购买
  8. 6.2.1mnist _eval
  9. css 颜色渐变的方法
  10. C语言for循环使用方法