function gridcolor(varargin) % % function gridcolor([h_axes], [xcolor], [ycolor], [zcolor]) % % Use this function to change the color of gridlines to a color different to the label and box % color, which is currently not implemented in Matlab. % (-> http://www.mathworks.com/support/solutions/data/1-1PAYMC.html?solution=1-1PAYMC) % % Input parameters (all optional) % ------------------------------- % hAx Handle of axis resp. array of handles to several axes, first arg. if specified % xyzcolor Color specification (e.g. 'r' or [1 0 0]) % % Syntax % ------ % gridcolor Change/update the current axis (gca) with the default grid color (cstd) % gridcolor(hAx) Change/update axis(axes) with handle(s) hAx with the default grid color (cstd) % gridcolor(hAx, col) Change/update axis(axes) (hAx) with grid color col (e.g. 'r' or [1 0 0]) % % Notes % ----- % This function creates a second "empty" axis, which only contains the grid lines, as suggested % in the Matlab support page. Additionally this "grid" axis is linked to the original axis to % enable correct behavior during zooming and paning. % From version 0.99 it is also possible to issue commands like "grid on" or "set(gca,'xminorGrid','on')", % which will update the axis accordingly % % The list of % linked properties includes everything I can think of, which may "disalign" the two axes. The % linking updates the second axis automatically, so you should be able to do all sorts of zooming, % paning, changing axis limits, axis directions, etc. If you are experiencing unwanted changes in % the overall display of your plot (e.g. dataaspectratio ...) you may want to take out some of the % properties in this line. % % For Matlab 6 (or lower) gridcolor will not notice any changes on the axis (e.g. 'xlim') % If you do change these parameters you will have to call gridcolor again, to update the gridlines !!! % % Example (execute one command after the other ...) % ------------------------------------------------- % plot([1 20],[1 50],'k'); % gridcolor('r') % set(gca,'gridlinestyle','-','minorgridlinestyle',':'); grid on % set(gca,'xminorgrid','on') % view(3); gridcolor([1 0 0],'g','b') % % Author % ------ % Sebastian Hoelz % IFM-GEOMAR % s[->Insert my family name<-]ATifm-geomar.de % % Version 0.95 - 10.06.2009 % Color of box was still displayed incorrectly ... hopefully fixed correctly this time. % Added some more relevant properties to link ... % % Version 0.94 - 10.01.2009 % Color of box was displayed incorrectly due to wrong stacking. % Changed: ax2('color','w'),uistack(ax2,'bottom'),ax1('color','none') % % Version 0.93 - 01.09.2008 % Included bug fix, which was caused by Matlabs version command % Gridstate (on/off) is now transfered from ax1->ax2, before turning it off for ax1 (s. lines 120ff.) % % Version 0.92 - 10.08.2006 % Changed the stack order of the reference axis (now bottom) and the "color-axis" (now top) % Removed the linkaxis-command for Matlab 6.5 and lower, since it does not exist in this version % % Version 0.91 - 31.01.2006 % Original Release cstd = [.8 .8 .8]; % Standard color persistent show_only_once % Parsing input with recursive calls to this function, % if less than 4 input arguments are supplied % ---------------------------------------------------- error(nargchk(0, 4, nargin)) if nargin==0 gridcolor(gca); return elseif nargin>=1 && nargin<4 a1 = varargin{1}; if iscolor(a1) % First argument seems to be a color spec. !!! gridcolor(gca,varargin{:}); return elseif length(a1)>1 % First argument might be an array with handles of axes for i=1:length(a1); gridcolor(a1(i),varargin{2:end}); end; return else % Check if argument is an axis handle if ~ishandle(a1) || ~strcmpi(get(a1,'type'),'axes'); error('Input argument is not an axis handle'); end if nargin == 1 % See if grid-axis already exists (-> axis is updated without color change!) ax2 = getappdata(a1,'hGridAxis'); if ~isempty(ax2) && ishandle(ax2); cxyz=get(ax2,{'xcolor','ycolor','zcolor'}); else cxyz={cstd, cstd, cstd}; end gridcolor(a1,cxyz{:}); return elseif nargin == 2 gridcolor(a1,varargin{2},varargin{2},varargin{2}); return elseif nargin == 3 gridcolor(a1,varargin{2},varargin{3},cstd); return end end end % Get / create grid axis ax1 = varargin{1}; ax2 = getappdata(ax1,'hGridAxis'); if isempty(ax2) ax2 = copyobj(ax1,get(ax1,'parent')); setappdata(ax1,'hGridAxis',ax2) uistack(ax2,'top') set(ax2,'xticklabel','','yticklabel','','zticklabel','','handlevisibility','off','hittest','off','color','none') set(ax1,'deletefcn',{@hGridAxis_delete, ax2}) CreatePropertyListener(ax1,ax2) end set(ax2,'xcolor',varargin{2},'ycolor',varargin{3},'zcolor',varargin{4},'handlevisibility','off','hittest','off') % Set linked properties if any(exist('linkprop','file') == [2 5]) % Matlab version 7 (or higher) hlink = linkprop([ax2 ax1],{'CameraPosition','CameraUpVector','CameraTarget','CameraViewAngle', ... 'xscale','yscale','zscale','xlim','ylim','zlim','xdir','ydir','zdir', ... 'xtick','ytick','ztick','tickdir','ticklength', ... 'XAxisLocation','YAxisLocation', ... 'PlotBoxAspectRatio','Dataaspectratio','position','units','Projection','box','linewidth','visible'}); setappdata(ax1,'axes_linkprop',hlink); else % Matlab 6.5 and lower, will probably not work ... set(ax2,{'CameraPosition','CameraUpVector', 'gridlinestyle','minorgridlinestyle',... 'xscale','yscale','zscale','xlim','ylim','zlim', 'xdir','ydir','zdir'}, ... get(ax1, {'CameraPosition','CameraUpVector','gridlinestyle','minorgridlinestyle',... 'xscale','yscale','zscale','xlim','ylim','zlim', 'xdir','ydir','zdir'})) if isempty(show_only_once) warning('GridColor:OldMatlabVersion', ... '\n\t"gridcolor" will only work properly for Matlab 7.0 or higher. \n\tNo support for Matlab 6.x or lower.') show_only_once = 1; end end end % ------------------------ function out = iscolor(in) % See if input argument is a valid Matlab color specification out = (ischar(in) && any(strcmpi(in,{'y','m','c','r','g','b','w','k'}))) || (isnumeric(in) && length(in)==3 && all(in>=0) && all(in<=1)); end % --------------------------- function hGridAxis_delete(varargin) try delete(varargin{3}); end end function CreatePropertyListener(ax1,ax2) % This is adapted from Yair Altman's submission "PropListener" (see FEX) % Create property listener for grid-calls h_ax1 = handle(ax1); props = {'XGrid' 'YGrid' 'ZGrid' 'XMinorGrid' 'YMinorGrid' 'ZMinorGrid' 'MinorGridLineStyle' 'GridLineStyle'}; event = 'PropertyPostSet'; callback = {@UpdateGridStyle,ax1,ax2,props}; for i = 1:length(props); hSrc(i) = h_ax1.findprop(props{i}); end hl = handle([]); hl = handle.listener(h_ax1, hSrc, event, callback); % Persist property listeners (or remove if empty callback) p = findprop(h_ax1, 'Listeners__'); if (isempty(p)) p = schema.prop(h_ax1, 'Listeners__', 'handle vector'); set(p, 'AccessFlags.Serialize', 'off', 'AccessFlags.Copy', 'off', 'FactoryValue', [], 'Visible', 'off'); end % filter out any non-handles h_ax1.Listeners__ = h_ax1.Listeners__(ishandle(h_ax1.Listeners__)); h_ax1.Listeners__ = [h_ax1.Listeners__; hl]; end function UpdateGridStyle(varargin) ax1 = varargin{3}; h_ax1 = handle(ax1); ax2 = varargin{4}; props = varargin{5}; set(ax2, props, get(ax1,props)) % % % tmp = h_ax1.Listeners__; % h_ax1.Listeners__ = []; % set(ax1,'xgrid','off', 'ygrid','off','zgrid','off','xminorgrid','off','yminorgrid','off','zminorgrid','off') % h_ax1.Listeners__ = tmp; end