NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/gliderproc/trunk/MATLAB/plots/mmpolar.m

Revision 495 (checked in by cbc, 11 years ago)

Initial import of Stark code.

Line 
1 function out=mmpolar(varargin)
2 %MMPOLAR Polar Plot with Settable Properties.
3 % MMPOLAR(Theta,Rho) creates a polar coordinate plot using the angle Theta
4 % in RADIANS and radius in Rho. Rho can contain negative values.
5 % MMPOLAR(Theta,Rho,S) creates the plot using the line spec given by S. See
6 % the function PLOT for information about S.
7 % MMPOLAR(Theta1,Rho1,S1,Theta2,Rho2,S2,...) plots all the defined curves.
8 %
9 % MMPOLAR(Theta1,Rho1,S1,...,'PName',PValue,...) plots all defined curves,
10 % and sets plot property names to the corresponding property values.
11 % MMPOLAR(Theta1,Rho1,S1,...,P) plots all the defined curves, and uses the
12 % structure P having fieldnames equal to plot property names to set
13 % corresponding property values contained in the associated fields.
14 %
15 % H=MMPOLAR(Theta,Rho,...) returns handles to lines or lineseries objects.
16 % For example, set(H,'LineWidth',2) sets all linewidths to 2 points.
17 % Note: 'LineWidth' is NOT a property that can be set with MMPOLAR. It must
18 % be set as shown above by using the SET function on the line handles H.
19 %
20 % MMPOLAR('PName',PValue,...) sets the property names to the corresponding
21 % property values. See below for property name/value pairs. Just as with
22 % the function SET 'PName' is case insensitive and need only be unique.
23 % MMPOLAR with no input argument returns a structure with fieldnames equal
24 % to property names each containing the associated property values.
25 % MMPOLAR(P) sets property values using the structure P as described above.
26 % MMPOLAR('PName') returns the property value associated with 'PName'.
27 % MMPOLAR({'PName1','PName2',...}) returns multiple property values in a
28 % cell array.
29 % MMPOLAR(Hax,...) uses the axes having handle Hax.
30 %
31 % Examples: MMPOLAR(Theta,Rho,S,'Style','compass') creates a polar plot with
32 % theta=0 pointing North and theta increasing in the clockwise direction.
33 %
34 % MMPOLAR(Theta,Rho,S) creates a cartesian polar plot where theta=0 is along
35 % the x-axis and theta increases in the counterclockwise direction.
36 %
37 % MMPOLAR works with HOLD, XLABEL, YLABEL, TITLE, ZOOM, SUBPLOT
38 % but does not work with AXIS, GRID (Use MMPOLAR properties to set these)
39 %
40 % See also POLAR, PLOT, HOLD
41 %
42 % PROPERTY          VALUE {Default}  DESCRIPTION
43 % Style             {cartesian} | compass  shortcut to two common polar
44 %                     styles. Cartesian: theta=0 points east and increases
45 %                     going north. Compass: theta=0 points north and
46 %                     increases going east. See TDirection and TZeroDirection.
47 % Axis              {on} | off  shortcut for grids, ticks, border,
48 %                     backgroundcolor, visibility
49 % Border            {on} | off  shortcut for axis border, tick mark visibility.
50 % Grid              {on} | off  shortcut for visibility of rho and theta grids
51 % RLimit            [Rmin Rmax] rho axis limits, may be negative values
52 % TLimit            [Tmin Tmax] theta axis limits in RADIANS
53 % RTickUnits        {''} string added to last rho tick label to denote units
54 % TTickScale        {degrees} | radians  theta axis tick label scaling
55 % TDirection        cw | {ccw} direction of increasing theta
56 % TZeroDirection    North | {East} | South | West  theta=0 axis direction
57 %
58 % BackgroundColor   {w}  colorspec for axis background color
59 % BorderColor       {k} colorspec for axis border and tick mark colors
60 % FontName          string  font name for tick labels
61 % FontSize          scalar  font size for tick labels
62 % FontWeight        {normal} | bold  font weight for tick labels
63 % TickLength        {.02} normalized length of rho and theta axis tick marks
64 %
65 % RGridColor        {k} colorspec for rho axis grid color
66 % RGridLineStyle    - | -- | {:} | -.  rho axis grid line style
67 % RGridLineWidth    {0.5}  rho axis grid line width in points
68 % RGridVisible      {on} | off  rho axis grid visibility
69 % RTickAngle        [scalar]  angular position of rho axis tick labels in
70 %                             TTickScale units
71 % RTickOffset       {.04} Normalized radial offset for rho tick labels
72 % RTickLabel        string cell array containing rho axis tick labels
73 % RTickLabelVisible {on} | off  visibility of rho axis tick labels
74 % RTickLabelHalign  {center} | left | right  horizontal
75 %                             alignment of rho axis tick labels
76 % RTickLabelValign  {middle} | top | cap | baseline | bottom  vertical
77 %                             alignment of rho axis tick labels
78 % RTickValue        [vector]  vector containing rho axis tick positions
79 % RTickVisible      {on} | off  rho axis tick visibility
80 %
81 % TGridColor        colorspec for theta axis grid color
82 % TGridLineStyle    - | -- | {:} | -.  theta axis grid line style
83 % TGridLineWidth    {0.5}  theta axis grid line width in points
84 % TGridVisible      {on} | off  theta axis grid visibility
85 % TTickDelta        theta axis tick spacing in TTickScale units
86 %                   {15 degrees or pi/12 radians}
87 % TTickDirection    {in} | out  direction of theta tick marks
88 % TTickOffset       {.08} normalized radial offset of theta tick labels
89 % TTickLabel        string cell array containing theta axis tick labels
90 % TTickLabelVisible {on} | off  visiblity of theta axis tick labels
91 % TTickSign         {+-} | + sign of theta tick labels
92 % TTickValue        [vector]  vector of theta ticks in TTickScale units
93 % TTickVisible      {on} | off  theta axis tick visibility
94
95 % D.C. Hanselman, University of Maine, Orono, ME 04469
96 % MasteringMatlab@yahoo.com
97 % Mastering MATLAB 7
98 % 2005-04-25, 2006-01-18, 2006-04-06, 2006-05-17, 2006-05-18
99 % 2006-10-03, 2007-03-04, 2008-03-18
100
101 %--------------------------------------------------------------------------
102 % Parse Inputs                                                 Parse Inputs
103 %--------------------------------------------------------------------------
104 % Find MMPOLAR axes if it exists
105 nargi=nargin;
106 % find MMPOLAR axes if it is supplied or if it is the current axes
107 if nargi>0 && isscalar(varargin{1}) && ishandle(varargin{1})
108    HAxes=varargin{1}; % see if first argument is an MMPOLAR axes
109    if strcmp(get(HAxes,'Tag'),'MMPOLAR_Axes')
110       HFig=ancestor(HAxes,'figure');
111       HoldIsON=strcmp(get(HAxes,'nextplot'),'add')...
112             && strcmp(get(HFig,'nextplot'),'add');
113       P=getappdata(HAxes,'MMPOLAR_Properties');
114       Pfn=fieldnames(P);
115       varargin(1)=[]; % strip initial axes handle off varargin
116       nargi=nargi-1;  % varargin now contains rest of input arguments
117    else
118       local_error('First Argument is Not a Valid MMPOLAR Axes Handle.')
119    end
120 else % see if MMPOLAR axes is current axes
121    HFig=get(0,'CurrentFigure');
122    if isempty(HFig)
123       HAxes=[];
124       Pfn=fieldnames(local_getDefaults);
125       HoldIsON=false;
126    else
127       HAxes=get(HFig,'CurrentAxes');
128       if isempty(HAxes)
129          Pfn=fieldnames(local_getDefaults);
130          HoldIsON=false;
131       else
132          if strcmp(get(HAxes,'Tag'),'MMPOLAR_Axes')
133             HoldIsON=strcmp(get(HAxes,'nextplot'),'add')...
134                   && strcmp(get(HFig,'nextplot'),'add');
135             P=getappdata(HAxes,'MMPOLAR_Properties');
136             Pfn=fieldnames(P);
137          else % no MMPOLAR axes exists
138             HAxes=[];
139             Pfn=fieldnames(local_getDefaults);
140             HoldIsON=false;
141             set(HAxes,'NextPlot','replace') % hold off
142          end
143       end
144    end
145 end
146 %--------------------------------------------------------------------------
147 % Consider input arguments                         Consider input arguments
148 %--------------------------------------------------------------------------
149 if nargi==0   % MMPOLAR() MMPOLAR() MMPOLAR() MMPOLAR() MMPOLAR() MMPOLAR()
150    if ~isempty(HAxes)
151       out=P; % return property structure if it exists
152       return
153    else
154       local_error('No MMPOLAR Axes exists or is not Current Axes.')
155    end
156 end
157 if nargi==1   % Consider SET and GET Requests Consider SET and GET Requests
158    if ~isempty(HAxes)
159       arg=varargin{1};
160       if ischar(arg)   % MMPOLAR('Pname') MMPOLAR('Pname') MMPOLAR('Pname')
161          [fn,errmsg]=local_isfield(Pfn,arg);
162          error(errmsg)
163          out=P.(fn);
164          return
165       elseif iscellstr(arg)              % MMPOLAR({'PName1','PName2',...})
166          nc=length(arg);
167          out=cell(1,nc);
168          for k=1:nc
169             [fn,errmsg]=local_isfield(Pfn,arg{k});
170             error(errmsg)
171             out{k}=P.(fn);
172          end
173          return
174       elseif isstruct(arg)    % MMPOLAR(S) MMPOLAR(S) MMPOLAR(S) MMPOLAR(S)
175          Sfn=fieldnames(arg);
176          for k=1:length(Sfn)
177             [fn,errmsg]=local_isfield(Pfn,Sfn{k});
178             error(errmsg)
179             S.(fn)=arg.(Sfn{k});
180          end
181          local_updatePlot(HAxes,S);
182          return
183       else
184          local_error('Unknown Input Argument.')
185       end
186    else
187       local_error('No MMPOLAR exists or is not Current Axes.')
188    end
189 end
190 %           MMPOLAR('PName1',PValue1,'PName2',PValue2,'PName3',PValue3,...)
191 if rem(nargi,2)==0 && ischar(varargin{1}) && ~isempty(HAxes)
192    for k=1:2:nargi-1
193       PName=varargin{k};
194       if ischar(PName)
195          [fn,errmsg]=local_isfield(Pfn,PName);
196          error(errmsg)
197          S.(fn)=varargin{k+1};
198       else
199          local_error('String Input Property Name Argument Expected.')
200       end
201    end
202    local_updatePlot(HAxes,S)
203    return
204 elseif ischar(varargin{1})      % Unknown Input Unknown Input Unknown Input
205    local_error('Unknown Input Arguments or NO MMPOLAR Axes Exists.')
206    
207 elseif isnumeric(varargin{1})%MMPOLAR(Theta,Rho,...) MMPOLAR(Theta,Rho,...)
208    % find out if there are appended 'PName',PValue pairs or a structure P
209    last=[];
210    k=3; % 'Pname' or P can't appear before 3rd argument
211    while k<=nargi
212       vark=varargin{k};
213       k=k+1;
214       if ischar(vark)
215          fn=local_isfield(Pfn,vark);
216          if ~isempty(fn)
217             if isempty(last)
218                last=k-1;
219             end
220             S.(fn)=varargin{k};
221             k=k+1; % skip known PValue
222          end
223       elseif isstruct(vark) % found appended structure
224          if isempty(last)
225             last=k-1;
226          end
227          Sfn=fieldnames(vark);
228          for ki=1:length(Sfn)
229             [fn,errmsg]=local_isfield(Pfn,Sfn{ki});
230             error(errmsg)
231             S.(fn)=vark.(Sfn{ki});
232          end
233       end
234    end
235    if ~isempty(last)
236       varargin(last:end)=[]; % strip properties and values from input
237    end
238 else
239    local_error('Unknown Input Arguments.')
240 end
241 %--------------------------------------------------------------------------
242 % Now have valid data for plotting         Now have valid data for plotting
243 %--------------------------------------------------------------------------
244 if HoldIsON % a current held plot exists
245    
246    D=getappdata(HAxes,'MMPOLAR_Data');                    % get stored data
247    P=getappdata(HAxes,'MMPOLAR_Properties');
248    
249    tmpaxes=axes('Position',get(HAxes,'Position'));
250    try % the plot function should work with new data
251       Hlines=plot(tmpaxes,varargin{:});
252    catch
253       delete(tmpaxes)
254       local_error('Input Arguments Not Understood.')
255    end
256    D.TData=[D.TData; get(Hlines,{'XData'})];   % add to held data
257    D.RData=[D.RData; get(Hlines,{'YData'})];
258    D.LineColor=[D.LineColor; get(Hlines,{'Color'})];
259    D.LineStyle=[D.LineStyle; get(Hlines,{'LineStyle'})];
260    D.Marker=[D.Marker; get(Hlines,{'Marker'})];
261    D.NumLines=length(D.TData);
262    
263    delete(Hlines)                % got the data, lines are no longer needed
264    delete(D.HLines)              % delete original lines as well
265    
266    set(tmpaxes,'NextPlot','add') % hold on
267    for k=1:D.NumLines        % plot ALL data to find new RTicks and RLimits
268       plot(tmpaxes,D.TData{k},D.RData{k})
269    end
270    P.RLimit=get(tmpaxes,'YLim');                          % Rho axis limits
271    P.RTickValue=get(tmpaxes,'YTick');              % Default Rho axis ticks
272    delete(tmpaxes)                        % Temporary axes no longer needed
273    [P,D]=local_getRTickValue(HAxes,P,D);              % get rho tick values
274    
275    D.RDataN=cell(D.NumLines,1);
276    for k=1:D.NumLines % normalize rho data for plotting
277       D.TData(k)={mod(D.TData{k},2*pi)}; % map theta into [0 2*pi]
278       D.RDataN(k)={(D.RData{k}-D.RMin)/D.RLimitDiff};
279    end
280    
281    P.TLimit=[0 2*pi];                                    % plot full circle
282    [P,D]=local_getTTickValue(P,D);                  % get theta tick values
283    [P,D]=local_placeAxesPatch(HAxes,P,D,1);% draw axes patch, border, ticks
284    [P,D]=local_placeRGrid(HAxes,P,D,1);                     % Draw Rho Grid
285    [P,D]=local_placeTGrid(HAxes,P,D,1);                   % Draw Theta Grid
286    [P,D]=local_placeTTickLabel(HAxes,P,D,1);        % Add Theta Tick Labels
287    [P,D]=local_placeRTickLabel(HAxes,P,D,1);         % Add Rho Tick Lablels
288      
289 else % Hold is OFF
290    
291    try % the plot function should work now
292       HAxes=newplot; % create axes
293       D.HLines=plot(HAxes,varargin{:});
294    catch
295       delete(gcf)
296       local_error('Input Arguments Not Understood.')
297    end
298    HFig=ancestor(HAxes,'figure');
299    D.NumLines=length(D.HLines);                  % get all data for storage
300    D.TData=get(D.HLines,{'XData'});
301    D.RData=get(D.HLines,{'YData'});
302    D.LineColor=get(D.HLines,{'Color'});
303    D.LineStyle=get(D.HLines,{'LineStyle'});
304    D.Marker=get(D.HLines,{'Marker'});
305    
306    P=local_getDefaults;          % get default properties, update as needed
307    
308    P.RLimit=get(HAxes,'YLim');                            % Rho axis limits
309    P.RTickValue=get(HAxes,'YTick');                % Default Rho axis ticks
310    [P,D]=local_getRTickValue(HAxes,P,D);              % get rho tick values
311    
312    D.RDataN=cell(D.NumLines,1);
313    for k=1:D.NumLines                              % Condition plotted data
314       % wrap angles into first revolution
315       D.TData{k}=mod(D.TData{k},2*pi);
316       % normalize rho data for plotting
317       D.RDataN(k)={(D.RData{k}-D.RMin)/D.RLimitDiff};
318    end
319    P.TLimit=[0 2*pi];                                    % plot full circle
320    [P,D]=local_getTTickValue(P,D);                  % get theta tick values
321    delete(D.HLines)         % clear cartesian lines, then create polar axes
322    [P,D]=local_placeAxesPatch(HAxes,P,D);  % draw axes patch, border, ticks
323    [P,D]=local_placeRGrid(HAxes,P,D);                       % Draw Rho Grid
324    [P,D]=local_placeTGrid(HAxes,P,D);                     % Draw Theta Grid
325    [P,D]=local_placeTTickLabel(HAxes,P,D);          % Add Theta Tick Labels
326    [P,D]=local_placeRTickLabel(HAxes,P,D);           % Add Rho Tick Lablels
327
328 end
329
330 xylims=[-1 1]*1.08;
331 % Finalize Axes View                                     Finalize Axes View
332 set(HAxes,'DataAspectRatio',[1 1 1],....
333           'XLimMode','manual','YLimMode','manual',...
334           'XLim',xylims,'YLim',xylims,...
335           'Visible','Off','Tag','MMPOLAR_Axes')
336 Hlabels=get(HAxes,{'Xlabel','YLabel', 'Title'});
337 set([Hlabels{:}],'Visible','on') % make labels visible
338
339 % Plot the Data                                               Plot the Data
340 D.HLines=zeros(D.NumLines,1);      % storage for lineseries handles
341 set([HFig,HAxes],'NextPlot','add') % hold on
342 for k=1:D.NumLines                 % plot the normalized data
343    tdata=D.TData{k};
344    rdata=D.RDataN{k};
345    xdata=rdata.*cos(tdata);
346    ydata=rdata.*sin(tdata);
347    D.HLines(k)=plot(HAxes,xdata,ydata,...
348                   'Color',D.LineColor{k},...
349                   'LineStyle',D.LineStyle{k},...
350                   'Marker',D.Marker{k});
351 end
352 if HoldIsON
353    set([HFig,HAxes],'NextPlot','add') % hold on
354 else
355    set([HFig,HAxes],'NextPlot','replace') % hold off
356 end
357
358 % Store Data                                                     Store Data
359 setappdata(HAxes,'MMPOLAR_Properties',P)
360 setappdata(HAxes,'MMPOLAR_Data',D)
361
362 if nargout % output handles if requested
363    out=D.HLines;
364 end
365
366 % Update Plot with 'PName' PValue pairs if they exist
367 if exist('S','var')==1
368    local_updatePlot(HAxes,S)
369 end
370 %--------------------------------------------------------------------------
371 %--------------------------------------------------------------------------
372 % Local Functions                                           Local Functions
373 %--------------------------------------------------------------------------
374 function local_updatePlot(HAxes,S)              % local_updatePlot(HAxes,S)
375 % update MMPOLAR plot properties
376 % S contains known properties
377
378 P=getappdata(HAxes,'MMPOLAR_Properties');
379 D=getappdata(HAxes,'MMPOLAR_Data');
380 Sfn=fieldnames(S);
381
382 for kk=1:length(Sfn)
383    switch Sfn{kk}
384    case 'Axis'                                                       % Axis
385       [istrue,onoff]=local_isonoff(S.Axis);
386       if istrue
387          set(D.HAPatch,'Visible',onoff)
388          set(D.HRGrid,'Visible',onoff)
389          set(D.HTGrid,'Visible',onoff)
390          set(D.HRTick,'Visible',onoff)
391          set(D.HTTick,'Visible',onoff)
392          set(D.HRTickLabel,'Visible',onoff)
393          set(D.HTTickLabel,'Visible',onoff)
394          P.RGridVisible=onoff;
395          P.TGridVisible=onoff;
396          P.RTickLabelVisible=onoff;
397          P.TTickLabelVisible=onoff;         
398       else
399          local_error('Unknown ''Axis'' Property Value.')
400       end
401    case 'BackgroundColor'                                 % BackgroundColor
402       [istrue,cs]=local_iscolorspec(S.BackgroundColor);
403       if istrue
404          set(D.HAPatch,'FaceColor',cs)
405          P.BackgroundColor=cs;
406       else
407          local_error('Unknown ''BackgroundColor'' Property Value.')
408       end
409    case 'Border'                                                   % Border
410       [istrue,onoff]=local_isonoff(S.Border);
411       if istrue && strcmp(onoff,'on')
412          set(D.HAPatch,'EdgeColor',P.BorderColor)
413          set(D.HTTick,'Visible','on')
414          set(D.HRTick,'Visible','on')
415          P.RTickVisible='on';
416          P.TTickVisibel='on';
417       elseif istrue && strcmp(onoff,'off')
418          set(D.HAPatch,'EdgeColor','none')
419          set(D.HTTick,'Visible','off')
420          set(D.HRTick,'Visible','off')
421          P.RTickVisible='off';
422          P.TTickVisibel='off';
423       else
424          local_error('Unknown ''Border'' Property Value.')
425       end
426    case 'BorderColor'                                         % BorderColor
427       [istrue,cs]=local_iscolorspec(S.BorderColor);
428       if istrue
429          P.BorderColor=cs;
430          set(D.HAPatch,'EdgeColor',cs)
431          set(D.HRTick,'Color',cs)
432          set(D.HTTick,'Color',cs)
433       else
434          local_error('Unknown ''BorderColor'' Property Value.')
435       end
436    case 'FontName'                                               % FontName
437       if ischar(S.FontName) && any(strcmpi(listfonts,S.FontName))
438          set([D.HRTickLabel; D.HTTickLabel],'FontName',S.FontName)
439          P.FontName=S.FontName;
440       else
441          local_error('Unknown ''FontName'' Property Value.')
442       end
443    case 'FontSize'                                               % FontSize
444       if isnumeric(S.FontSize) && isscalar(S.FontSize)
445          set([D.HRTickLabel; D.HTTickLabel],'FontSize',S.FontSize)
446          P.FontSize=S.FontSize;
447       else
448          local_error('Unknown ''FontSize'' Property Value.')
449       end
450    case 'FontWeight'                                           % FontWeight
451       if ischar(S.FontWeight) && ...
452             (strncmpi(S.FontWeight,'normal',3)...
453             ||strncmpi(S.FontWeight,'bold',3))
454          set([D.HRTickLabel; D.HTTickLabel],'FontWeight',S.FontWeight)
455          P.FontWeight=S.FontWeight;
456       else
457          local_error('Unknown ''FontWeight'' Property Value.')
458       end     
459    case 'Grid'                                                       % Grid
460       [istrue,onoff]=local_isonoff(S.Grid);
461       if istrue
462          set(D.HRGrid,'Visible',onoff)
463          set(D.HTGrid,'Visible',onoff)
464          P.Grid=onoff;
465          P.RGridVisible=onoff;
466          P.TGridVisible=onoff;
467       else
468          local_error('Unknown ''Grid'' Property Value.')
469       end
470    case 'RGridColor'                                           % RGridColor
471       [istrue,cs]=local_iscolorspec(S.RGridColor);
472       if istrue
473          set(D.HRGrid,'Color',cs)
474          set(D.HRTickLabel,'Color',cs)
475          P.RGridColor=cs;
476       else
477          local_error('Unknown ''RGridColor'' Property Value.')
478       end
479    case 'RGridLineStyle'                                   % RGridLineStyle
480       if local_islinespec(S.RGridLineStyle)
481          set(D.HRGrid,'LineStyle',S.RGridLineStyle)
482          P.RGridLineStyle=S.RGridLineStyle;
483       else
484          local_error('Unknown ''RGridLineStyle'' Property Value.')
485       end               
486    case 'RGridLineWidth'                                   % RGridLineWidth
487       if isnumeric(S.RGridLineWidth) && isscalar(S.RGridLineWidth)
488          set(D.HRGrid,'LineWidth',S.RGridLineWidth)
489          P.RGridLineWidth=S.RGridLineWidth;
490       else
491          local_error('Unknown ''RGridLineWidth'' Property Value.')
492       end
493    case 'RGridVisible'                                       % RGridVisible
494       [istrue,onoff]=local_isonoff(S.RGridVisible);
495       if istrue
496          set(D.HRGrid,'Visible',onoff)
497          P.RGridVisible=onoff;
498       else
499          local_error('Unknown ''RGridVisible'' Property Value.')
500       end     
501    case 'RLimit'                                                   % RLimit
502       if isnumeric(S.RLimit) && numel(S.RLimit)==2
503          S.RLimit=[min(S.RLimit) max(S.RLimit)];
504          S.RLimit(isinf(S.RLimit))=P.RLimit(isinf(S.RLimit));
505          [P,D]=local_getRTickValue(HAxes,P,D,S);
506          [P,D]=local_placeRGrid(HAxes,P,D,S);
507          [P,D]=local_placeRTickLabel(HAxes,P,D,S);
508          % rescale rho data to new limits
509          for k=1:length(D.RData)
510             D.RDataN(k)={(D.RData{k}-D.RMin)/D.RLimitDiff};
511             D.RDataN{k}(D.RDataN{k}>1)=NaN; % hide data outside limits
512             D.RDataN{k}(D.RDataN{k}<0)=NaN;
513             theta=D.TData{k};
514             xdata=D.RDataN{k}.*cos(theta);
515             ydata=D.RDataN{k}.*sin(theta);
516             set(D.HLines(k),'XData',xdata,'YData',ydata)
517          end
518       else
519          local_error('Unknown ''RLimit'' Property Value.')
520       end               
521    case 'RTickAngle'                                           % RTickAngle
522       if isnumeric(S.RTickAngle) && isscalar(S.RTickAngle)
523          rad=S.RTickAngle;
524          if strcmp(P.TTickScale,'degrees')
525             rad=S.RTickAngle*pi/180;
526          end
527          if P.TLimit(1)>P.TLimit(2) && (rad<P.TLimit(2) || rad>P.TLimit(1))
528             P.RTickAngle=S.RTickAngle;
529             D.RTickAngle=rad;
530          elseif rad>P.TLimit(1) && rad<P.TLimit(2)
531             P.RTickAngle=S.RTickAngle;
532             D.RTickAngle=rad;           
533          else
534             local_error('RTickAngle not within Theta Axis Limits.')
535          end
536          for k=1:D.RTickLabelN % ignore innermost tick
537             xdata=(P.RTickOffset+D.RTickRadius(k))*cos(D.RTickAngle);
538             ydata=(P.RTickOffset+D.RTickRadius(k))*sin(D.RTickAngle);
539             set(D.HRTickLabel(k),'Position',[xdata ydata])
540          end
541          phi=asin(P.TickLength./(2*D.RTickRadius));
542          tdata=[D.RTickAngle-phi; D.RTickAngle+zeros(size(D.RTickRadius))
543                 D.RTickAngle+phi; NaN(size(D.RTickRadius))];
544          rdata=[D.RTickRadius; D.RTickRadius
545                 D.RTickRadius; NaN(size(D.RTickRadius))];
546          xdata=rdata(:).*cos(tdata(:));
547          ydata=rdata(:).*sin(tdata(:));
548          set(D.HRTick,'XData',xdata,'YData',ydata) % move rho ticks
549       else
550          local_error('Unknown ''RTickAngle'' Property Value.')
551       end
552    case 'RTickLabel'                                           % RTickLabel
553       if iscellstr(S.RTickLabel)
554          NumS=length(S.RTickLabel);
555          for k=1:D.RTickLabelN
556             str=S.RTickLabel{rem(k-1,NumS)+1};
557             set(D.HRTickLabel(k),'String',str)
558          end         
559          P.RTickLabel=S.RTickLabel;
560       else
561          local_error('Unknown ''RTickLabel'' Property Value.')
562       end
563    case 'RTickLabelHalign'                               % RTickLabelHalign
564       fnames={'left' 'center' 'right'};
565       out=local_isfield(fnames,S.RTickLabelHalign);
566       if ~isempty(out)
567          P.RTickLabelHalign=out;
568          set(D.HRTickLabel,'HorizontalAlignment',out)
569       else
570          local_error('Unknown ''RTickLabelHalign'' Property Value.')
571       end         
572    case 'RTickLabelValign'                               % RTickLabelValign
573       fnames={'top' 'cap' 'middle' 'baseline' 'bottom'};
574       out=local_isfield(fnames,S.RTickLabelValign);
575       if ~isempty(out)
576          P.RTickLabelValign=out;
577          set(D.HRTickLabel,'VerticalAlignment',out)
578       else
579          local_error('Unknown ''RTickLabelValign'' Property Value.')
580       end
581    case 'RTickLabelVisible'                             % RTickLabelVisible
582       [istrue,onoff]=local_isonoff(S.RTickLabelVisible);
583       if istrue
584          set(D.HRTickLabel,'Visible',onoff)
585          P.RTickLabelVisible=onoff;
586       else
587          local_error('Unknown ''RTickLabelVisible'' Property Value.')
588       end
589    case 'RTickOffset'                                         % RTickOffset
590       if isnumeric(S.RTickOffset) && isscalar(S.RTickOffset)
591          P.RTickOffset=S.RTickOffset;
592          for k=1:D.RTickLabelN
593             xdata=(P.RTickOffset+D.RTickRadius(k))*cos(D.RTickAngle);
594             ydata=(P.RTickOffset+D.RTickRadius(k))*sin(D.RTickAngle);
595             set(D.HRTickLabel(k),'Position',[xdata ydata])
596          end
597       else
598           local_error('Unknown ''RTickOffset'' Property Value.')
599       end
600    case 'RTickUnits'                                           % RTickUnits
601       if ischar(S.RTickUnits)
602          tmp=char(get(D.HRTickLabel(end),'String'));
603          if ~isempty(P.RTickUnits)
604             idx=strfind(tmp,P.RTickUnits);
605             tmp=[tmp(1:idx(end)-1) S.RTickUnits];
606          else
607             tmp=[tmp S.RTickUnits]; %#ok
608          end
609          set(D.HRTickLabel(end),'String',tmp)
610          P.RTickUnits=S.RTickUnits;
611       else
612          local_error('Unknown ''RTickUnits'' Property Value.')
613       end
614    case 'RTickValue'                                           % RTickValue
615       if isnumeric(S.RTickValue) && numel(S.RTickValue)>0
616          S.RTickValue=S.RTickValue(S.RTickValue>=P.RLimit(1)...
617             & S.RTickValue<=P.RLimit(2));
618          if length(S.RTickValue)>1
619             P.RTickValue=S.RTickValue;
620             D.RTickLabelN=length(P.RTickValue);
621             D.RTickRadius=(P.RTickValue-D.RMin)/D.RLimitDiff;
622             [P,D]=local_placeRGrid(HAxes,P,D,S);
623             [P,D]=local_placeRTickLabel(HAxes,P,D,S);
624          end
625       else
626          local_error('Unknown ''RTickValue'' Property Value.')
627       end
628    case 'RTickVisible'                                       % RTickVisible
629       [istrue,onoff]=local_isonoff(S.RTickVisible);
630       if istrue
631          set(D.HRTick,'Visible',onoff)
632          P.RTickVisible=onoff;
633       else
634          local_error('Unknown ''RTickVisible'' Property Value.')
635       end
636    case 'Style'                                                     % Style
637       if strncmpi(S.Style,'cartesian',3)   % Cartesian style
638          set(HAxes,'View',[0 90])
639          P.TDirection='ccw';
640          P.TZeroDirection='east';
641          P.Style='cartesian';
642       elseif strncmpi(S.Style,'compass',3) % Compass style
643          set(HAxes,'View',[90 -90])
644          P.TDirection='cw';
645          P.TZeroDirection='north';
646          P.Style='compass';
647       else
648          local_error('Unknown ''Style'' Property Value.')
649       end
650    case 'TDirection'                                           % TDirection
651       if ischar(S.TDirection) && strcmpi(S.TDirection,'cw')
652          P.TDirection='cw';
653          if strcmp(P.TZeroDirection,'north')
654             set(HAxes,'View',[90 -90])
655          elseif strcmp(P.TZeroDirection,'east')
656             set(HAxes,'View',[0 -90])
657          elseif strcmp(P.TZeroDirection,'south')
658             set(HAxes,'View',[270 -90])
659          elseif strcmp(P.TZeroDirection,'west')
660             set(HAxes,'View',[180 -90])
661          end
662       elseif ischar(S.TDirection) && strcmpi(S.TDirection,'ccw')
663          P.TDirection='ccw';
664          if strcmp(P.TZeroDirection,'north')
665             set(HAxes,'View',[270 90])
666          elseif strcmp(P.TZeroDirection,'east')
667             set(HAxes,'View',[0 90])
668          elseif strcmp(P.TZeroDirection,'south')
669             set(HAxes,'View',[90 90])
670          elseif strcmp(P.TZeroDirection,'west')
671             set(HAxes,'View',[180 90])
672          end
673       else
674          local_error('Unknown ''TDirection'' Property Value.')
675       end
676       P.Style='unknown';
677    case 'TGridColor'                                           % TGridColor
678       [istrue,cs]=local_iscolorspec(S.TGridColor);
679       if istrue
680          set(D.HTGrid,'Color',cs)
681          set(D.HTTickLabel,'Color',cs)
682          P.TGridColor=cs;
683       else
684          local_error('Unknown ''TGridColor'' Property Value.')
685       end
686    case 'TGridLineStyle'                                   % TGridLineStyle
687       if local_islinespec(S.TGridLineStyle)
688          set(D.HTGrid,'LineStyle',S.TGridLineStyle)
689          P.TGridLineStyle=S.TGridLineStyle;
690       else
691          local_error('Unknown ''TGridLineStyle'' Property Value.')
692       end
693    case 'TGridLineWidth'                                   % TGridLineWidth
694       if isnumeric(S.TGridLineWidth) && isscalar(S.TGridLineWidth)
695          set(D.HTGrid,'LineWidth',S.TGridLineWidth)
696          P.TGridLineWidth=S.TGridLineWidth;
697       else
698          local_error('Unknown ''TGridLineWidth'' Property Value.')
699       end
700    case 'TGridVisible'                                       % TGridVisible
701       [istrue,onoff]=local_isonoff(S.TGridVisible);
702       if istrue
703          set(D.HTGrid,'Visible',onoff)
704          P.TGridVisible=onoff;
705       else
706          local_error('Unknown ''TGridVisible'' Property Value.')
707       end     
708    case 'TickLength'                                           % TickLength
709       if isnumeric(S.TickLength) && isscalar(S.TickLength)
710          P.TickLength=max(min(abs(S.TickLength),0.1),.001);
711          tdir=2*strcmp(P.TTickDirection,'in')-1;
712          tdata=[D.TTickValue;D.TTickValue;NaN(1,D.TTickLabelN)];
713          rdata=[ones(1,D.TTickLabelN)
714                 (1-tdir*P.TickLength)+zeros(1,D.TTickLabelN)
715                 NaN(1,D.TTickLabelN)];
716          xdata=rdata(:).*cos(tdata(:));
717          ydata=rdata(:).*sin(tdata(:));
718          set(D.HTTick,'XData',xdata,'YData',ydata) % theta ticks
719          phi=asin(P.TickLength./(2*D.RTickRadius));
720          tdata=[D.RTickAngle-phi; D.RTickAngle+zeros(size(D.RTickRadius))
721                 D.RTickAngle+phi; NaN(size(D.RTickRadius))];
722          rdata=[D.RTickRadius; D.RTickRadius
723                 D.RTickRadius; NaN(size(D.RTickRadius))];
724          xdata=rdata(:).*cos(tdata(:));
725          ydata=rdata(:).*sin(tdata(:));
726          set(D.HRTick,'XData',xdata,'YData',ydata) % rho ticks
727       else
728          local_error('Unknown ''TickLength'' Property Value.')
729       end
730    case 'TLimit'                                                   % TLimit
731       if isnumeric(S.TLimit) && numel(S.TLimit)==2
732          if abs(diff(S.TLimit))>1.9*pi   % make full circle if close
733             P.TLimit=[0 2*pi];
734          else
735             P.TLimit=mod(S.TLimit,2*pi); % move limits to range 0 to 2pi
736          end
737          [P,D]=local_getTTickValue(P,D,S);
738          [P,D]=local_placeAxesPatch(HAxes,P,D,S);
739          [P,D]=local_placeRGrid(HAxes,P,D,S);
740          [P,D]=local_placeTGrid(HAxes,P,D,S);
741          [P,D]=local_placeTTickLabel(HAxes,P,D,S);
742          [P,D]=local_placeRTickLabel(HAxes,P,D,S);
743          for k=1:length(D.TData) % hide data outside TLimits
744             tdata=D.TData{k};
745             if P.TLimit(1)>P.TLimit(2)
746                tdata(tdata<P.TLimit(1) & tdata>P.TLimit(2))=NaN;
747             else           
748                tdata(tdata<P.TLimit(1) | tdata>P.TLimit(2))=NaN;
749             end
750             xdata=D.RDataN{k}.*cos(tdata);
751             ydata=D.RDataN{k}.*sin(tdata);
752             set(D.HLines(k),'XData',xdata,'YData',ydata)
753          end
754       else
755          local_error('Unknown ''TLimit'' Property Value.')
756       end
757    case 'TTickDelta'                                           % TTickDelta
758       if isnumeric(S.TTickDelta) && isscalar(S.TTickDelta)
759          if strcmp(P.TTickScale,'degrees')
760             P.TTickDelta=min(max(abs(S.TTickDelta),5),90);
761          else
762             P.TTickDelta=min(max(abs(S.TTickDelta),pi/36),pi/2);
763          end
764          [P,D]=local_getTTickValue(P,D,S);
765          [P,D]=local_placeTGrid(HAxes,P,D,S);
766          [P,D]=local_placeTTickLabel(HAxes,P,D,S);
767       else
768          local_error('Unknown ''TTickDelta'' Property Value.')
769       end
770    case 'TTickDirection'                                   % TTickDirection
771       if ischar(S.TTickDirection) &&...
772         (strcmpi(S.TTickDirection,'out') || strcmpi(S.TTickDirection,'in'))
773          P.TTickDirection=S.TTickDirection;
774          tdir=2*strcmp(P.TTickDirection,'in')-1;
775          tdata=[D.TTickValue;D.TTickValue;NaN(1,D.TTickLabelN)];
776          rdata=[ones(1,D.TTickLabelN)
777                 (1-tdir*P.TickLength)+zeros(1,D.TTickLabelN)
778                 NaN(1,D.TTickLabelN)];
779          xdata=rdata(:).*cos(tdata(:));
780          ydata=rdata(:).*sin(tdata(:));
781          set(D.HTTick,'XData',xdata,'YData',ydata) % theta ticks
782       else
783          local_error('Unknown ''TTickDirection'' Property Value.')
784       end
785    case 'TTickLabel'                                           % TTickLabel
786       if iscellstr(S.TTickLabel)
787          NumS=length(S.TTickLabel);
788          for k=1:D.TTickLabelN
789             str=S.TTickLabel{rem(k-1,NumS)+1};
790             set(D.HTTickLabel(k),'String',str)
791          end         
792          P.TTickLabel=S.TTickLabel;
793       else
794          local_error('Unknown ''TTickLabel'' Property Value.')
795       end
796    case 'TTickLabelVisible'                             % TTickLabelVisible
797       [istrue,onoff]=local_isonoff(S.TTickLabelVisible);
798       if istrue
799          set(D.HTTickLabel,'Visible',onoff)
800          P.TTickLabelVisible=onoff;
801       else
802          local_error('Unknown ''TTickLabelVisible'' Property Value.')
803       end
804    case 'TTickOffset'                                         % TTickOffset
805       if isnumeric(S.TTickOffset) && isscalar(S.TTickOffset)
806          P.TTickOffset=S.TTickOffset;
807          for k=1:D.TTickLabelN
808             xdata=(1+P.TTickOffset)*cos(D.TTickValue(k));
809             ydata=(1+P.TTickOffset)*sin(D.TTickValue(k));
810             set(D.HTTickLabel(k),'Position',[xdata ydata])
811          end
812       else
813          local_error('Unknown ''TTickOffset'' Property Value.')
814       end
815    case 'TTickScale'                                           % TTickScale
816       if ischar(S.TTickScale) && strncmpi(S.TTickScale,'degrees',3)...
817                               && strcmp(P.TTickScale,'radians')
818          P.TTickScale='degrees';
819          P.TTickDelta=P.TTickDelta*180/pi;
820          P.RTickAngle=P.RTickAngle*180/pi;
821          [P,D]=local_getTTickValue(P,D,S);
822          [P,D]=local_placeTTickLabel(HAxes,P,D,S);
823       elseif ischar(S.TTickScale) && strncmpi(S.TTickScale,'radians',3)...
824                                   && strcmp(P.TTickScale,'degrees')
825          P.TTickScale='radians';
826          P.TTickDelta=P.TTickDelta*pi/180;
827          P.RTickAngle=P.RTickAngle*pi/180;
828          [P,D]=local_getTTickValue(P,D,S);
829          [P,D]=local_placeTTickLabel(HAxes,P,D,S);
830       elseif ~ischar(S.TTickScale)
831          local_error('Unknown ''TTickScale'' Property Value.')
832       end
833    case 'TTickSign'                                             % TTickSign
834       if ischar(S.TTickSign)
835          if strcmp(S.TTickSign,'+')
836             P.TTickSign='+';
837          else
838             P.TTickSign='+-';
839          end
840          [P,D]=local_getTTickValue(P,D,S);
841          [P,D]=local_placeTTickLabel(HAxes,P,D,S);
842       else
843          local_error('Unknown ''TTickSign'' Property Value.')
844       end
845    case 'TTickValue'                                           % TTickValue
846       if isnumeric(S.TTickValue) && numel(S.TTickValue)>0
847          TTick=S.TTickValue(:)';
848          if strcmp(P.TTickScale,'degrees')
849             TTick=TTick*pi/180;
850          end
851          if P.TLimit(1)>P.TLimit(2)
852             idx=TTick<=P.TLimit(2) | TTick>=P.TLimit(1); % keepers
853          else
854             idx=TTick>=P.TLimit(1) & TTick<=P.TLimit(2); % keepers
855          end
856          S.TTickValue=S.TTickValue(idx);
857          if length(S.TTickValue)>1
858             P.TTickValue=S.TTickValue(:)';
859             D.TTickValue=TTick(idx);
860             D.TTickLabelN=length(P.TTickValue);
861             [P,D]=local_placeTGrid(HAxes,P,D,S);
862             [P,D]=local_placeTTickLabel(HAxes,P,D,S);
863          end
864       else
865          local_error('Unknown ''TTickValue'' Property Value.')
866       end
867    case 'TTickVisible'                                       % TTickVisible
868       [istrue,onoff]=local_isonoff(S.TTickVisible);
869       if istrue
870          set(D.HTTick,'Visible',onoff)
871          P.TTickVisible=onoff;
872       else
873          local_error('Unknown ''RTickVisible'' Property Value.')
874       end
875    case 'TZeroDirection'                                   % TZeroDirection
876       if ischar(S.TZeroDirection) && strncmpi(S.TZeroDirection,'north',1)
877          P.TZeroDirection='north';
878          if strcmp(P.TDirection,'ccw')
879             set(HAxes,'View',[270 90])
880          elseif strcmp(P.TDirection,'cw')
881             set(HAxes,'View',[90 -90])
882          end
883       elseif ischar(S.TZeroDirection) && strncmpi(S.TZeroDirection,'east',1)
884          P.TZeroDirection='east';
885          if strcmp(P.TDirection,'ccw')
886             set(HAxes,'View',[0 90])
887          elseif strcmp(P.TDirection,'cw')
888             set(HAxes,'View',[0 -90])
889          end
890       elseif ischar(S.TZeroDirection) && strncmpi(S.TZeroDirection,'south',1)
891          P.TZeroDirection='south';
892          if strcmp(P.TDirection,'ccw')
893             set(HAxes,'View',[90 90])
894          elseif strcmp(P.TDirection,'cw')
895             set(HAxes,'View',[270 -90])
896          end
897       elseif ischar(S.TZeroDirection) && strncmpi(S.TZeroDirection,'west',1)
898          P.TZeroDirection='west';
899          if strcmp(P.TDirection,'ccw')
900             set(HAxes,'View',[180 90])
901          elseif strcmp(P.TDirection,'cw')
902             set(HAxes,'View',[180 -90])
903          end
904       else
905          local_error('Unknown ''TZeroDirection'' Property Value.')
906       end
907       P.Style='unknown';
908    end
909 end
910 setappdata(HAxes,'MMPOLAR_Properties',P)
911 setappdata(HAxes,'MMPOLAR_Data',D)
912 %--------------------------------------------------------------------------
913 %--------------------------------------------------------------------------
914 function [out,errmsg]=local_isfield(fnames,str)             % local_isfield
915 % compare str to fnames, if found, return complete fieldname
916 % otherwise return error and empty string.
917 % fnames is cell array, str is a string
918 % outputs are strings
919
920 % look for exact match first
921 idx=find(strcmpi(fnames,str));
922
923 if isempty(idx) % no exact match, so look for more general match
924    idx=find(strncmpi(str,fnames,max(length(str),2)));
925 end
926 if numel(idx)==1 % unique match found
927    out=fnames{idx};
928    errmsg='';
929 else             % trouble
930    out='';
931    errmsg=sprintf('Unknown or Not Unique Property: %s',str);
932 end
933 %--------------------------------------------------------------------------
934 function [istrue,cs]=local_iscolorspec(arg)             % local_iscolorspec
935 % see if arg is a valid color specification including 'none'
936 rgb={[1 0 0],[0 1 0],[0 0 1],[0 1 1],[1 0 1],[1 1 0],[0 0 0],[1 1 1],'none'};
937 cc='rgbcmykwn';
938 istrue=false;
939 cs=[];
940 if ~isempty(arg) && ischar(arg)
941    idx=find(arg(1)==cc);
942    if ~isempty(idx)
943       istrue=true;
944       cs=rgb{idx};
945    end
946 elseif ~isempty(arg) && isnumeric(arg)
947    istrue=all(size(arg)==[1 3])...
948       && all(arg>=0) && all(arg<=1);
949    cs=arg;
950 else
951    istrue=false;
952 end
953 %--------------------------------------------------------------------------
954 function istrue=local_islinespec(arg)                    % local_islinespec
955 % see if arg is a valid line style specification
956 str={'-','-.','--',':'};
957 if isempty(arg)
958    istrue=false;
959 elseif ischar(arg) && length(arg)<3
960    istrue=any(strncmp(str,arg,length(arg)));
961 else
962    istrue=false;
963 end
964 %--------------------------------------------------------------------------
965 function [istrue,s]=local_isonoff(arg)                      % local_isonoff
966 % see if arg is either on or off
967 istrue=false;
968 s='';
969 if ~isempty(arg) && ischar(arg) && strcmpi(arg,'on')
970    istrue=true;
971    s='on';
972 elseif ~isempty(arg) && ischar(arg) && strcmpi(arg,'off')
973    istrue=true;
974    s='off';
975 end
976 %--------------------------------------------------------------------------
977 function local_error(arg) 
978 % Add message identifier to error message and post error
979 if ~isempty(arg) && ischar(arg)
980    error('MMPOLAR:error',arg)
981 end
982 %--------------------------------------------------------------------------
983 function [P,D]=local_placeAxesPatch(HAxes,P,D,S)  %#ok local_placeAxesPatch
984 % Draw Axes Border and Patch
985 tinc=pi/250;
986 if P.TLimit(1)>P.TLimit(2)
987    theta=[P.TLimit(1):tinc:(P.TLimit(2)+2*pi-eps) P.TLimit(2)+2*pi];
988 else
989    theta=[P.TLimit(1):tinc:P.TLimit(2)-eps P.TLimit(2)];
990 end   
991 costheta=cos(theta);
992 sintheta=sin(theta);
993 if abs(diff(P.TLimit))<2*(1-eps)*pi; % less than 4 quadrant box
994    xdata=[0 costheta 0];
995    ydata=[0 sintheta 0];
996 else % four quadrant box
997    xdata=costheta;
998    ydata=sintheta;
999 end
1000 % let the axes grow for less than 4 quadrant box
1001 set(HAxes,'Xlim',[min(xdata) max(xdata)],'Ylim',[min(ydata) max(ydata)])
1002 if nargin==3 % new plot
1003    D.HAPatch=patch('XData',xdata,'YData',ydata,...
1004       'Parent',HAxes,...
1005       'LineStyle','-',...
1006       'Linewidth',2*P.RGridLineWidth,...
1007       'EdgeColor',P.BorderColor,...
1008       'FaceColor',P.BackgroundColor,...
1009       'HandleVisibility','off',...
1010       'HitTest','off');
1011 else % old plot, update data
1012    set(D.HAPatch,'XData',xdata,'YData',ydata)
1013 end
1014 %--------------------------------------------------------------------------
1015 function [P,D]=local_placeRGrid(HAxes,P,D,S)          %#ok local_placeRGrid
1016 tinc=pi/250;
1017 if P.TLimit(1)>P.TLimit(2)
1018    theta=[P.TLimit(1):tinc:(P.TLimit(2)+2*pi-eps) P.TLimit(2)+2*pi];
1019 else
1020    theta=[P.TLimit(1):tinc:P.TLimit(2)-eps P.TLimit(2)];
1021 end   
1022 costheta=cos(theta);
1023 sintheta=sin(theta);
1024 xdata=[];
1025 ydata=[];
1026 % no outer grid if outer tick is at outer RLimit
1027 D.RGridN=length(P.RTickValue(P.RTickValue<P.RLimit(2)));
1028 for k=1:D.RGridN
1029    xdata=[xdata D.RTickRadius(k)*costheta NaN];  %#ok
1030    ydata=[ydata D.RTickRadius(k)*sintheta NaN];  %#ok
1031 end
1032 if nargin<4 % new grid
1033    D.HRGrid=line(xdata,ydata,...
1034       'Parent',HAxes,...
1035       'LineStyle',P.RGridLineStyle,...
1036       'LineWidth',P.RGridLineWidth,...
1037       'Color',P.RGridColor,...
1038       'HandleVisibility','off',...
1039       'HitTest','off');
1040 else
1041    set(D.HRGrid,'Xdata',xdata,'YData',ydata)
1042 end
1043 % Draw Rho Axis Tick Marks
1044 phi=asin(P.TickLength./(2*D.RTickRadius));
1045 tdata=[D.RTickAngle-phi; D.RTickAngle+zeros(size(D.RTickRadius))
1046        D.RTickAngle+phi; NaN(size(D.RTickRadius))];
1047 rdata=[D.RTickRadius; D.RTickRadius
1048        D.RTickRadius; NaN(size(D.RTickRadius))];
1049 xdata=rdata(:).*cos(tdata(:));
1050 ydata=rdata(:).*sin(tdata(:));
1051 if nargin==3 % new plot
1052    D.HRTick=line(xdata,ydata,...
1053       'Parent',HAxes,...
1054       'LineStyle','-',...
1055       'LineWidth',2*P.RGridLineWidth,...
1056       'Color',P.BorderColor,...
1057       'HandleVisibility','off',...
1058       'HitTest','off');
1059 else % old plot, update data
1060    set(D.HRTick,'XData',xdata,'YData',ydata)
1061 end
1062 %--------------------------------------------------------------------------
1063 function [P,D]=local_placeRTickLabel(HAxes,P,D,S)%#ok local_placeRTickLabel
1064 % Draw Rho Tick Labels
1065 D.RScale=floor(log10(max(abs(P.RTickValue))));
1066 if abs(D.RScale)<2
1067    D.RScale=0;
1068 end
1069 P.RTickLabel=cell(D.RTickLabelN,1);
1070 if nargin==4 % delete old labels and create new ones
1071    delete(D.HRTickLabel)
1072 end
1073 D.HRTickLabel=zeros(D.RTickLabelN,1);
1074 for k=1:D.RTickLabelN
1075    xdata=(P.RTickOffset+D.RTickRadius(k))*cos(D.RTickAngle);
1076    ydata=(P.RTickOffset+D.RTickRadius(k))*sin(D.RTickAngle);
1077    P.RTickLabel{k}=num2str(P.RTickValue(k)*10^(-D.RScale));
1078    if (k==D.RTickLabelN) && (D.RScale~=0)
1079       P.RTickLabel{k}=[P.RTickLabel{k} sprintf('\\times10^{%d}',D.RScale)];
1080    end
1081    D.HRTickLabel(k)=text(xdata,ydata,P.RTickLabel{k},...
1082       'Parent',HAxes,...
1083       'Color',P.TGridColor,...
1084       'FontName',P.FontName,...
1085       'FontSize',P.FontSize,...
1086       'FontWeight',P.FontWeight',...
1087       'HorizontalAlignment',P.RTickLabelHalign,...
1088       'VerticalAlignment',P.RTickLabelValign,...
1089       'Clipping','off',...
1090       'HandleVisibility','off',...
1091       'HitTest','off');
1092 end
1093 %--------------------------------------------------------------------------
1094 function [P,D]=local_getRTickValue(HAxes,P,D,S)       % local_getRTickValue
1095 % get RTicks
1096 if nargin==4 % updating current ticks given new rho axis limits
1097    tmpaxes=axes('Position',get(HAxes,'Position'));
1098    line([0 1],S.RLimit,'Parent',tmpaxes);
1099    P.RTickValue=get(tmpaxes,'YTick');
1100    P.RLimit=S.RLimit;
1101    delete(tmpaxes) % got ticks, don't need axes anymore
1102 end
1103 %P.RTickValue(end)=P.RLimit(2); % place last tick at outer rho limit
1104 NumRTick=length(P.RTickValue); % reduce ticks if too many
1105 if NumRTick>6
1106    if rem(NumRTick,2)~=0  % odd number keep alternate ones
1107       P.RTickValue=P.RTickValue(1:2:end);
1108    else % even number, add one tick, then keep alternate ones
1109       if P.RTickValue(1)==0     % keep lowest tick if zero, add one at outside
1110          P.RTickValue=[P.RTickValue(1:2:end-1) ...
1111                         2*P.RTickValue(end)-P.RTickValue(end-1)];
1112          P.RTickValue(P.RTickValue>P.RLimit(2))=[]; % no label past limit
1113       else                    % add one tick at inside
1114          P.RTickValue=[2*P.RTickValue(1)-P.RTickValue(2)...
1115                         P.RTickValue(2:2:end)];
1116       end
1117       P.RLimit(1)=P.RTickValue(1); % make first tick lower axis limit
1118    end
1119 end
1120 if NumRTick<3
1121    m=sum(P.RTickValue)/2;
1122    P.RTickValue(3)=P.RTickValue(2);
1123    P.RTickValue(2)=m;
1124 end
1125 D.RLimitDiff=diff(P.RLimit);
1126 D.RMin=P.RLimit(1);
1127 if abs(P.RTickValue(1)-P.RLimit(1)) < abs(D.RLimitDiff)/100
1128    P.RTickValue(1)=[]; % throw out inner tick if at inner axis limit
1129 end
1130 D.RTickRadius=(P.RTickValue-D.RMin)/D.RLimitDiff;
1131 D.RTickLabelN=length(P.RTickValue);
1132 %--------------------------------------------------------------------------
1133 function [P,D]=local_placeTGrid(HAxes,P,D,S)          %#ok local_placeTGrid
1134 xdata=[];
1135 ydata=[];
1136 costheta=cos(D.TTickValue);
1137 sintheta=sin(D.TTickValue);
1138 % no grid on first or last ticks are axis limits if less than 4 quadrants
1139 ki=1;
1140 ke=length(D.TTickValue);
1141 if abs(diff(P.TLimit))<2*(1-eps)*pi; % less than 4 quadrant box
1142    ki=1+(D.TTickValue(1)==P.TLimit(1));
1143    ke=length(D.TTickValue)-(D.TTickValue(end)==P.TLimit(2));
1144 end
1145 D.TGridN=ke-ki+1;
1146 for k=ki:ke
1147    xdata=[xdata 0 costheta(k) NaN];  %#ok
1148    ydata=[ydata 0 sintheta(k) NaN];  %#ok
1149 end
1150 if nargin<4 % new grid
1151    D.HTGrid=line(xdata,ydata,...
1152       'Parent',HAxes,...
1153       'LineStyle',P.TGridLineStyle,...
1154       'LineWidth',P.TGridLineWidth,...
1155       'Color',P.TGridColor,...
1156       'HandleVisibility','off',...
1157       'HitTest','off');
1158 else
1159    set(D.HTGrid,'Xdata',xdata,'YData',ydata)
1160 end
1161 % Draw Theta Axis Tick Marks
1162 tdir=2*strcmp(P.TTickDirection,'in')-1;
1163 tdata=[D.TTickValue; D.TTickValue; NaN(1,D.TTickLabelN)];
1164 rdata=[ones(1,D.TTickLabelN)
1165        (1-tdir*P.TickLength)+zeros(1,D.TTickLabelN)
1166        NaN(1,D.TTickLabelN)];
1167 xdata=rdata(:).*cos(tdata(:));
1168 ydata=rdata(:).*sin(tdata(:));
1169 if nargin==3 % new plot
1170    D.HTTick=line(xdata,ydata,...
1171       'Parent',HAxes,...
1172       'LineStyle','-',...
1173       'LineWidth',2*P.RGridLineWidth,...
1174       'Color',P.BorderColor,...
1175       'Clipping','off',...
1176       'HandleVisibility','off',...
1177       'HitTest','off');
1178 else % old plot, update data
1179    set(D.HTTick,'XData',xdata,'YData',ydata)
1180 end
1181 %--------------------------------------------------------------------------
1182 function [P,D]=local_placeTTickLabel(HAxes,P,D,S)%#ok local_placeTTickLabel
1183 % Draw Theta Ticks
1184 if nargin==4 % delete old labels and create new ones
1185    delete(D.HTTickLabel)
1186 end
1187 P.TTickLabel=cell(D.TTickLabelN,1);
1188 D.HTTickLabel=zeros(D.TTickLabelN,1);
1189 for k=1:D.TTickLabelN % label ticks at theta axis limits
1190    xdata=(1+P.TTickOffset)*cos(D.TTickValue(k));
1191    ydata=(1+P.TTickOffset)*sin(D.TTickValue(k));
1192    if strcmp(P.TTickScale,'radians')
1193       [n,d]=rat(P.TTickValue(k)/pi); % ticks as fractions
1194       if n==0
1195          Tstr='0';
1196       elseif n==1 && d==1
1197          Tstr='\pi';
1198       elseif n==-1 && d==1
1199          Tstr='-\pi';
1200       elseif n==1
1201          Tstr=['\pi/' num2str(d)];
1202       elseif n==-1
1203          Tstr=['-\pi/' num2str(d)];
1204       elseif d==1
1205          Tstr=[num2str(n) '\pi'];
1206       else
1207          Tstr=[num2str(n) '\pi/' num2str(d)];
1208       end
1209       P.TTickLabel{k}=Tstr;
1210    else % degrees
1211       P.TTickLabel{k}=[num2str(P.TTickValue(k)) '\circ'];
1212       if P.TTickValue(k)==-180
1213          P.TTickLabel{k}=['\pm' P.TTickLabel{k}(2:end)];
1214       end
1215    end
1216    D.HTTickLabel(k)=text(xdata,ydata,P.TTickLabel{k},...
1217       'Parent',HAxes,...
1218       'Color',P.TGridColor,...
1219       'FontName',P.FontName,...
1220       'FontSize',P.FontSize,...
1221       'FontWeight',P.FontWeight',...
1222       'HorizontalAlignment','center',...
1223       'VerticalAlignment','middle',...
1224       'Clipping','off',...
1225       'HandleVisibility','off',...
1226       'HitTest','off');
1227 end
1228 %--------------------------------------------------------------------------
1229 function [P,D]=local_getTTickValue(P,D,S)          %#ok local_getTTickValue
1230 % Get Theta Ticks
1231 if strcmp(P.TTickScale,'degrees') % ticks are in degrees
1232    TTick=0:P.TTickDelta:360; % possible ticks
1233    if P.TLimit(1)>P.TLimit(2)
1234       idx=TTick<=P.TLimit(2)*180/pi | TTick>=P.TLimit(1)*180/pi; % keepers
1235    else
1236       idx=TTick>=P.TLimit(1)*180/pi & TTick<=P.TLimit(2)*180/pi; % keepers
1237    end
1238    P.TTickValue=TTick(idx);
1239    P.TTickValue=unique(rem(P.TTickValue,360)); % get unique ticks
1240    D.TTickValue=P.TTickValue*pi/180; % store ticks in radians
1241    if strcmp(P.TTickSign,'+-')
1242       tmp=P.TTickValue>=180;
1243       P.TTickValue(tmp)=P.TTickValue(tmp)-360;
1244    end
1245 else                          % ticks are in radians
1246    TTick=(0:P.TTickDelta*180/pi:360)*pi/180; % possible ticks
1247    if P.TLimit(1)>P.TLimit(2)
1248       idx=TTick<=P.TLimit(2) | TTick>=P.TLimit(1); % keepers
1249    else
1250       idx=TTick>=P.TLimit(1) & TTick<=P.TLimit(2); % keepers
1251    end
1252    P.TTickValue=TTick(idx);
1253    P.TTickValue=unique(rem(P.TTickValue,2*pi)); % get unique ticks
1254    D.TTickValue=P.TTickValue; % store ticks in radians for plotting
1255    if strcmp(P.TTickSign,'+-')
1256       tmp=P.TTickValue>=pi;
1257       P.TTickValue(tmp)=P.TTickValue(tmp)-2*pi;
1258    end
1259 end
1260 D.TTickLabelN=length(D.TTickValue);
1261 kmid=max(1,floor(length(P.TTickValue)/2));
1262 P.RTickAngle=(D.TTickValue(kmid)+D.TTickValue(kmid+1))/2;
1263 D.RTickAngle=P.RTickAngle;
1264 if strcmp(P.TTickScale,'degrees')
1265    P.RTickAngle=P.RTickAngle*180/pi;
1266 end
1267 %--------------------------------------------------------------------------
1268 function out=local_getDefaults                          % local_getDefaults
1269 out.Style='cartesian';
1270 out.Axis='on';
1271 out.Border='on';
1272 out.Grid='on';
1273 out.RLimit=[0 1];
1274 out.TLimit=[0 2*pi];
1275 out.RTickUnits='';
1276 out.TTickScale='degrees';
1277 out.TDirection='ccw';
1278 out.TZeroDirection='east';
1279
1280 out.BackgroundColor=get(0,'defaultaxescolor');
1281 out.BorderColor=[0 0 0];
1282 out.FontName=get(0,'defaultaxesfontname');
1283 out.FontSize=get(0,'defaultaxesfontsize');
1284 out.FontWeight=get(0,'defaultaxesfontweight');
1285 out.TickLength=0.02;
1286
1287 out.RGridColor=get(0,'defaultaxesycolor');
1288 out.RGridLineStyle=get(0,'defaultaxesgridlinestyle');
1289 out.RGridLineWidth=get(0,'defaultaxeslinewidth');
1290 out.RGridVisible='on';
1291 out.RTickAngle=0;
1292 out.RTickOffset=0.04;
1293 out.RTickLabel='0|0.5|1.0';
1294 out.RTickLabelHalign='center';
1295 out.RTickLabelValign='middle';
1296 out.RTickLabelVisible='on';
1297 out.RTickValue=[0 .5 1];
1298 out.RTickVisible='on';
1299
1300 out.TGridColor=get(0,'defaultaxesxcolor');
1301 out.TGridVisible='on';
1302 out.TGridLineStyle=get(0,'defaultaxesgridlinestyle');
1303 out.TGridLineWidth=get(0,'defaultaxeslinewidth');
1304 out.TTickOffset=0.08;
1305 out.TTickDelta=15;
1306 out.TTickDirection='in';
1307 out.TTickLabel='';
1308 out.TTickLabelVisible='on';
1309 out.TTickSign='+-';
1310 out.TTickValue=0:15:359;
1311 out.TTickVisible='on';
1312 %--------------------------------------------------------------------------
1313 % Description of Plot Data Stored           Description of Plot Data Stored
1314 %--------------------------------------------------------------------------
1315 %
1316 % VARIABLE        TYPE        DESCRIPTION
1317 % D.TData         Cell        Raw input theta data
1318 % D.RData         Cell        Raw input rho data
1319 % D.RDataN        Cell        Normalized rho data
1320 % D.LineColor     Cell        Line colors of plotted data
1321 % D.LineStyle     Cell        Line styles of plotted data
1322 % D.Marker        Cell        Markers of plotted data
1323 % D.RLimitDiff    Double      Rho axis limit difference
1324 % D.RMin          Double      Rho axis minimum
1325 % D.RScale        Double      Power of ten scaling rho axis ticks
1326 % D.RTickAngle    Double      Angle of rho tick labels in radians
1327 % D.RTickRadius   Double      Radial position of rho tick labels
1328 % D.RGridN        Double      Number of rho axis grid lines
1329 % D.RTickLabelN   Double      Number of rho axis tick labels
1330 % D.TGridN        Double      Number of theta axis grid lines     
1331 % D.TTickLabelN   Double      Number of theta axis tick labels
1332 % D.TTickValue    Double      Theta tick values in RADIANS
1333 %--------------------------------------------------------------------------
1334 % Description of Stored Handles               Description of Stored Handles
1335 %--------------------------------------------------------------------------
1336 %
1337 % HANDLE          TYPE        DESCRIPTION
1338 % D.HAPatch       Patch       Axis background and border
1339 % D.HTTick        Line        Theta tick marks
1340 % D.HRTick        Line        Rho tick marks
1341 % D.HRGrid        Line        Rho grid
1342 % D.HTTickLabel   Text        Theta Tick Labels
1343 % D.HRTIckLabel   Text        Rho Tick Labels
1344 % D.HLines        Line        Plotted Data
1345 %
1346 %--------------------------------------------------------------------------
Note: See TracBrowser for help on using the browser.