📄 mmpolar.m
字号:
function out=mmpolar(varargin)
%MMPOLAR Polar Plot with Settable Properties.
% MMPOLAR(Theta,Rho) creates a polar coordinate plot using the angle Theta
% in RADIANS and radius in Rho. Rho can contain negative values.
% MMPOLAR(Theta,Rho,S) creates the plot using the line spec given by S. See
% the function PLOT for information about S.
% MMPOLAR(Theta1,Rho1,S1,Theta2,Rho2,S2,...) plots all the defined curves.
%
% MMPOLAR(Theta1,Rho1,S1,...,'PName',PValue,...) plots all defined curves,
% and sets plot property names to the corresponding property values.
% MMPOLAR(Theta1,Rho1,S1,...,P) plots all the defined curves, and uses the
% structure P having fieldnames equal to plot property names to set
% corresponding property values contained in the associated fields.
%
% H=MMPOLAR(Theta,Rho,...) returns handles to lines or lineseries objects.
% For example, set(H,'LineWidth',2) sets all linewidths to 2 points.
% Note: 'LineWidth' is NOT a property that can be set with MMPOLAR. It must
% be set as shown above by using the SET function on the line handles H.
%
% MMPOLAR('PName',PValue,...) sets the property names to the corresponding
% property values. See below for property name/value pairs. Just as with
% the function SET 'PName' is case insensitive and need only be unique.
% MMPOLAR with no input argument returns a structure with fieldnames equal
% to property names each containing the associated property values.
% MMPOLAR(P) sets property values using the structure P as described above.
% MMPOLAR('PName') returns the property value associated with 'PName'.
% MMPOLAR({'PName1','PName2',...}) returns multiple property values in a
% cell array.
% MMPOLAR(Hax,...) uses the axes having handle Hax.
%
% Examples: MMPOLAR(Theta,Rho,S,'Style','compass') creates a polar plot with
% theta=0 pointing North and theta increasing in the clockwise direction.
%
% MMPOLAR(Theta,Rho,S) creates a cartesian polar plot where theta=0 is along
% the x-axis and theta increases in the counterclockwise direction.
%
% MMPOLAR works with HOLD, XLABEL, YLABEL, TITLE, ZOOM, SUBPLOT
% but does not work with AXIS, GRID (Use MMPOLAR properties to set these)
%
% See also POLAR, PLOT, HOLD
%
% PROPERTY VALUE {Default} DESCRIPTION
% Style {cartesian} | compass shortcut to two common polar
% styles. Cartesian: theta=0 points east and increases
% going north. Compass: theta=0 points north and
% increases going east. See TDirection and TZeroDirection.
% Axis {on} | off shortcut for grids, ticks, border,
% backgroundcolor, visibility
% Border {on} | off shortcut for axis border, tick mark visibility.
% Grid {on} | off shortcut for visibility of rho and theta grids
% RLimit [Rmin Rmax] rho axis limits, may be negative values
% TLimit [Tmin Tmax] theta axis limits in RADIANS
% RTickUnits {''} string added to last rho tick label to denote units
% TTickScale {degrees} | radians theta axis tick label scaling
% TDirection cw | {ccw} direction of increasing theta
% TZeroDirection North | {East} | South | West theta=0 axis direction
%
% BackgroundColor {w} colorspec for axis background color
% BorderColor {k} colorspec for axis border and tick mark colors
% FontName string font name for tick labels
% FontSize scalar font size for tick labels
% FontWeight {normal} | bold font weight for tick labels
% TickLength {.02} normalized length of rho and theta axis tick marks
%
% RGridColor {k} colorspec for rho axis grid color
% RGridLineStyle - | -- | {:} | -. rho axis grid line style
% RGridLineWidth {0.5} rho axis grid line width in points
% RGridVisible {on} | off rho axis grid visibility
% RTickAngle [scalar] angular position of rho axis tick labels in
% TTickScale units
% RTickOffset {.04} Normalized radial offset for rho tick labels
% RTickLabel string cell array containing rho axis tick labels
% RTickLabelVisible {on} | off visibility of rho axis tick labels
% RTickLabelHalign {center} | left | right horizontal
% alignment of rho axis tick labels
% RTickLabelValign {middle} | top | cap | baseline | bottom vertical
% alignment of rho axis tick labels
% RTickValue [vector] vector containing rho axis tick positions
% RTickVisible {on} | off rho axis tick visibility
%
% TGridColor colorspec for theta axis grid color
% TGridLineStyle - | -- | {:} | -. theta axis grid line style
% TGridLineWidth {0.5} theta axis grid line width in points
% TGridVisible {on} | off theta axis grid visibility
% TTickDelta theta axis tick spacing in TTickScale units
% {15 degrees or pi/12 radians}
% TTickDirection {in} | out direction of theta tick marks
% TTickOffset {.08} normalized radial offset of theta tick labels
% TTickLabel string cell array containing theta axis tick labels
% TTickLabelVisible {on} | off visiblity of theta axis tick labels
% TTickSign {+-} | + sign of theta tick labels
% TTickValue [vector] vector of theta ticks in TTickScale units
% TTickVisible {on} | off theta axis tick visibility
% D.C. Hanselman, University of Maine, Orono, ME 04469
% MasteringMatlab@yahoo.com
% Mastering MATLAB 7
% 2005-04-25, 2006-01-18, 2006-04-06, 2006-05-17, 2006-05-18
% 2006-10-03, 2007-03-04, 2008-03-18
%--------------------------------------------------------------------------
% Parse Inputs Parse Inputs
%--------------------------------------------------------------------------
% Find MMPOLAR axes if it exists
nargi=nargin;
% find MMPOLAR axes if it is supplied or if it is the current axes
if nargi>0 && isscalar(varargin{1}) && ishandle(varargin{1})
HAxes=varargin{1}; % see if first argument is an MMPOLAR axes
if strcmp(get(HAxes,'Tag'),'MMPOLAR_Axes')
HFig=ancestor(HAxes,'figure');
HoldIsON=strcmp(get(HAxes,'nextplot'),'add')...
&& strcmp(get(HFig,'nextplot'),'add');
P=getappdata(HAxes,'MMPOLAR_Properties');
Pfn=fieldnames(P);
varargin(1)=[]; % strip initial axes handle off varargin
nargi=nargi-1; % varargin now contains rest of input arguments
else
local_error('First Argument is Not a Valid MMPOLAR Axes Handle.')
end
else % see if MMPOLAR axes is current axes
HFig=get(0,'CurrentFigure');
if isempty(HFig)
HAxes=[];
Pfn=fieldnames(local_getDefaults);
HoldIsON=false;
else
HAxes=get(HFig,'CurrentAxes');
if isempty(HAxes)
Pfn=fieldnames(local_getDefaults);
HoldIsON=false;
else
if strcmp(get(HAxes,'Tag'),'MMPOLAR_Axes')
HoldIsON=strcmp(get(HAxes,'nextplot'),'add')...
&& strcmp(get(HFig,'nextplot'),'add');
P=getappdata(HAxes,'MMPOLAR_Properties');
Pfn=fieldnames(P);
else % no MMPOLAR axes exists
HAxes=[];
Pfn=fieldnames(local_getDefaults);
HoldIsON=false;
set(HAxes,'NextPlot','replace') % hold off
end
end
end
end
%--------------------------------------------------------------------------
% Consider input arguments Consider input arguments
%--------------------------------------------------------------------------
if nargi==0 % MMPOLAR() MMPOLAR() MMPOLAR() MMPOLAR() MMPOLAR() MMPOLAR()
if ~isempty(HAxes)
out=P; % return property structure if it exists
return
else
local_error('No MMPOLAR Axes exists or is not Current Axes.')
end
end
if nargi==1 % Consider SET and GET Requests Consider SET and GET Requests
if ~isempty(HAxes)
arg=varargin{1};
if ischar(arg) % MMPOLAR('Pname') MMPOLAR('Pname') MMPOLAR('Pname')
[fn,errmsg]=local_isfield(Pfn,arg);
error(errmsg)
out=P.(fn);
return
elseif iscellstr(arg) % MMPOLAR({'PName1','PName2',...})
nc=length(arg);
out=cell(1,nc);
for k=1:nc
[fn,errmsg]=local_isfield(Pfn,arg{k});
error(errmsg)
out{k}=P.(fn);
end
return
elseif isstruct(arg) % MMPOLAR(S) MMPOLAR(S) MMPOLAR(S) MMPOLAR(S)
Sfn=fieldnames(arg);
for k=1:length(Sfn)
[fn,errmsg]=local_isfield(Pfn,Sfn{k});
error(errmsg)
S.(fn)=arg.(Sfn{k});
end
local_updatePlot(HAxes,S);
return
else
local_error('Unknown Input Argument.')
end
else
local_error('No MMPOLAR exists or is not Current Axes.')
end
end
% MMPOLAR('PName1',PValue1,'PName2',PValue2,'PName3',PValue3,...)
if rem(nargi,2)==0 && ischar(varargin{1}) && ~isempty(HAxes)
for k=1:2:nargi-1
PName=varargin{k};
if ischar(PName)
[fn,errmsg]=local_isfield(Pfn,PName);
error(errmsg)
S.(fn)=varargin{k+1};
else
local_error('String Input Property Name Argument Expected.')
end
end
local_updatePlot(HAxes,S)
return
elseif ischar(varargin{1}) % Unknown Input Unknown Input Unknown Input
local_error('Unknown Input Arguments or NO MMPOLAR Axes Exists.')
elseif isnumeric(varargin{1})%MMPOLAR(Theta,Rho,...) MMPOLAR(Theta,Rho,...)
% find out if there are appended 'PName',PValue pairs or a structure P
last=[];
k=3; % 'Pname' or P can't appear before 3rd argument
while k<=nargi
vark=varargin{k};
k=k+1;
if ischar(vark)
fn=local_isfield(Pfn,vark);
if ~isempty(fn)
if isempty(last)
last=k-1;
end
S.(fn)=varargin{k};
k=k+1; % skip known PValue
end
elseif isstruct(vark) % found appended structure
if isempty(last)
last=k-1;
end
Sfn=fieldnames(vark);
for ki=1:length(Sfn)
[fn,errmsg]=local_isfield(Pfn,Sfn{ki});
error(errmsg)
S.(fn)=vark.(Sfn{ki});
end
end
end
if ~isempty(last)
varargin(last:end)=[]; % strip properties and values from input
end
else
local_error('Unknown Input Arguments.')
end
%--------------------------------------------------------------------------
% Now have valid data for plotting Now have valid data for plotting
%--------------------------------------------------------------------------
if HoldIsON % a current held plot exists
D=getappdata(HAxes,'MMPOLAR_Data'); % get stored data
P=getappdata(HAxes,'MMPOLAR_Properties');
tmpaxes=axes('Position',get(HAxes,'Position'));
try % the plot function should work with new data
Hlines=plot(tmpaxes,varargin{:});
catch
delete(tmpaxes)
local_error('Input Arguments Not Understood.')
end
D.TData=[D.TData; get(Hlines,{'XData'})]; % add to held data
D.RData=[D.RData; get(Hlines,{'YData'})];
D.LineColor=[D.LineColor; get(Hlines,{'Color'})];
D.LineStyle=[D.LineStyle; get(Hlines,{'LineStyle'})];
D.Marker=[D.Marker; get(Hlines,{'Marker'})];
D.NumLines=length(D.TData);
delete(Hlines) % got the data, lines are no longer needed
delete(D.HLines) % delete original lines as well
set(tmpaxes,'NextPlot','add') % hold on
for k=1:D.NumLines % plot ALL data to find new RTicks and RLimits
plot(tmpaxes,D.TData{k},D.RData{k})
end
P.RLimit=get(tmpaxes,'YLim'); % Rho axis limits
P.RTickValue=get(tmpaxes,'YTick'); % Default Rho axis ticks
delete(tmpaxes) % Temporary axes no longer needed
[P,D]=local_getRTickValue(HAxes,P,D); % get rho tick values
D.RDataN=cell(D.NumLines,1);
for k=1:D.NumLines % normalize rho data for plotting
D.TData(k)={mod(D.TData{k},2*pi)}; % map theta into [0 2*pi]
D.RDataN(k)={(D.RData{k}-D.RMin)/D.RLimitDiff};
end
P.TLimit=[0 2*pi]; % plot full circle
[P,D]=local_getTTickValue(P,D); % get theta tick values
[P,D]=local_placeAxesPatch(HAxes,P,D,1);% draw axes patch, border, ticks
[P,D]=local_placeRGrid(HAxes,P,D,1); % Draw Rho Grid
[P,D]=local_placeTGrid(HAxes,P,D,1); % Draw Theta Grid
[P,D]=local_placeTTickLabel(HAxes,P,D,1); % Add Theta Tick Labels
[P,D]=local_placeRTickLabel(HAxes,P,D,1); % Add Rho Tick Lablels
else % Hold is OFF
try % the plot function should work now
HAxes=newplot; % create axes
D.HLines=plot(HAxes,varargin{:});
catch
delete(gcf)
local_error('Input Arguments Not Understood.')
end
HFig=ancestor(HAxes,'figure');
D.NumLines=length(D.HLines); % get all data for storage
D.TData=get(D.HLines,{'XData'});
D.RData=get(D.HLines,{'YData'});
D.LineColor=get(D.HLines,{'Color'});
D.LineStyle=get(D.HLines,{'LineStyle'});
D.Marker=get(D.HLines,{'Marker'});
P=local_getDefaults; % get default properties, update as needed
P.RLimit=get(HAxes,'YLim'); % Rho axis limits
P.RTickValue=get(HAxes,'YTick'); % Default Rho axis ticks
[P,D]=local_getRTickValue(HAxes,P,D); % get rho tick values
D.RDataN=cell(D.NumLines,1);
for k=1:D.NumLines % Condition plotted data
% wrap angles into first revolution
D.TData{k}=mod(D.TData{k},2*pi);
% normalize rho data for plotting
D.RDataN(k)={(D.RData{k}-D.RMin)/D.RLimitDiff};
end
P.TLimit=[0 2*pi]; % plot full circle
[P,D]=local_getTTickValue(P,D); % get theta tick values
delete(D.HLines) % clear cartesian lines, then create polar axes
[P,D]=local_placeAxesPatch(HAxes,P,D); % draw axes patch, border, ticks
[P,D]=local_placeRGrid(HAxes,P,D); % Draw Rho Grid
[P,D]=local_placeTGrid(HAxes,P,D); % Draw Theta Grid
[P,D]=local_placeTTickLabel(HAxes,P,D); % Add Theta Tick Labels
[P,D]=local_placeRTickLabel(HAxes,P,D); % Add Rho Tick Lablels
end
xylims=[-1 1]*1.08;
% Finalize Axes View Finalize Axes View
set(HAxes,'DataAspectRatio',[1 1 1],....
'XLimMode','manual','YLimMode','manual',...
'XLim',xylims,'YLim',xylims,...
'Visible','Off','Tag','MMPOLAR_Axes')
Hlabels=get(HAxes,{'Xlabel','YLabel', 'Title'});
set([Hlabels{:}],'Visible','on') % make labels visible
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -