drawing effect
tutorial section
basic drawing
The data is a numeric matrix:
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X);
RC=RC.draw();
change style
There are Patch
two Line
styles, Type
set the style by setting attributes:
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X,'Type','Patch');
RC=RC.draw();
add modify label add legend
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X);
RC.PropName={'建模','实验','编程','总结','撰写','创新','摸鱼'};
RC.ClassName={'同门A','同门B','同门C','同门D'};
RC=RC.draw();
RC.legend();
R-axis position and its range
Change the range to [2,10], and draw 2, 8, 9, 10 four tick marks:
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X);
RC.RLim=[2,10];
RC.RTick=[2,8:1:10];
RC=RC.draw();
RC.legend();
Modify axis properties
use:
- setThetaTick
- setRTick
Set the axis properties, for example, the theta axis becomes light red, and the R axis becomes light blue:
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X);
RC=RC.draw();
RC.legend();
RC.setThetaTick('LineWidth',2,'Color',[.6,.6,.8]);
RC.setRTick('LineWidth',1.5,'Color',[.8,.6,.6]);
Modify label properties
use:
- setPropLabel
- setRLabel
Modify attribute labels and R tick labels:
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X);
RC=RC.draw();
RC.legend();
RC.setPropLabel('FontSize',20,'FontName','Cambria','Color',[0,0,.8])
RC.setRLabel('FontSize',15,'FontName','Cambria','Color',[.8,0,0])
Modify the circular background
Decorate the background with setBkg
a function:
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X);
RC=RC.draw();
RC.legend();
RC.setBkg('FaceColor',[0,0,.1])
RC.setRLabel('Color','none')
Cosmetic Polygon
The two types of polygons are drawn with Patch
objects and Line
objects respectively. The decoration methods are slightly different, but they are all setPatchN
decorated with functions. The following is an example of modifying the color:
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X);
RC=RC.draw();
RC.legend();
colorList=[78 101 155;
138 140 191;
184 168 207;
231 188 198;
253 207 158;
239 164 132;
182 118 108]./255;
for n=1:RC.ClassNum
RC.setPatchN(n,'Color',colorList(n,:),'MarkerFaceColor',colorList(n,:))
end
X=randi([2,8],[4,7])+rand([4,7]);
RC=radarChart(X,'Type','Patch');
RC=RC.draw();
RC.legend();
colorList=[78 101 155;
138 140 191;
184 168 207;
231 188 198;
253 207 158;
239 164 132;
182 118 108]./255;
for n=1:RC.ClassNum
RC.setPatchN(n,'FaceColor',colorList(n,:),'EdgeColor',colorList(n,:))
end
Tool function complete code
classdef radarChart
% @author : slandarer
% gzh : slandarer随笔
properties
ax=[];Parent=[];arginList={
'ClassName','PropName','Type','Parent'}
XData;RTick=[];RLim=[];SepList=[1,1.2,1.5,2,2.5,3,4,5,6,8]
Type='Line';
PropNum;ClassNum
ClassName={
};
PropName={
};
BC=[198,199,201; 38, 74, 96; 209, 80, 51; 241,174, 44; 12,13,15;
102,194,165; 252,140, 98; 142,160,204; 231,138,195;
166,217, 83; 255,217, 48; 229,196,148; 179,179,179]./255;
% 句柄
ThetaTickHdl;RTickHdl;RLabelHdl;LgdHdl=[];
PatchHdlL;PatchHdlP;PropLabelHdl;BkgHdl
end
methods
function obj=radarChart(varargin)
if isa(varargin{
1},'matlab.graphics.axis.Axes')
obj.ax=varargin{
1};varargin(1)=[];
else
end
obj.XData=varargin{
1};varargin(1)=[];
obj.PropNum=size(obj.XData,2);
obj.ClassNum=size(obj.XData,1);
obj.RLim=[0,max(max(obj.XData))];
% 获取其他信息
for i=1:2:(length(varargin)-1)
tid=ismember(obj.arginList,varargin{
i});
if any(tid)
obj.(obj.arginList{
tid})=varargin{
i+1};
end
end
if isempty(obj.ax)&&(~isempty(obj.Parent))
obj.ax=obj.Parent;
end
if isempty(obj.ax)
obj.ax=gca;
end
obj.ax.NextPlot='add';
if isempty(obj.ClassName)
for i=1:obj.ClassNum
obj.ClassName{
i}=['class ',num2str(i)];
end
end
if isempty(obj.PropName)
for i=1:obj.PropNum
obj.PropName{
i}=['prop ',num2str(i)];
end
end
help radarChart
end
function obj=draw(obj)
obj.ax.XLim=[-1,1];
obj.ax.YLim=[-1,1];
obj.ax.XTick=[];
obj.ax.YTick=[];
obj.ax.XColor='none';
obj.ax.YColor='none';
obj.ax.PlotBoxAspectRatio=[1,1,1];
% 绘制背景圆形
tt=linspace(0,2*pi,200);
obj.BkgHdl=fill(obj.ax,cos(tt),sin(tt),[252,252,252]./255,'EdgeColor',[200,200,200]./255,'LineWidth',1);
% 绘制Theta刻度线
tn=linspace(0,2*pi,obj.PropNum+1);tn=tn(1:end-1);
XTheta=[cos(tn);zeros([1,obj.PropNum]);nan([1,obj.PropNum])];
YTheta=[sin(tn);zeros([1,obj.PropNum]);nan([1,obj.PropNum])];
obj.ThetaTickHdl=plot(obj.ax,XTheta(:),YTheta(:),'Color',[200,200,200]./255,'LineWidth',1);
% 绘制R刻度线
if isempty(obj.RTick)
dr=diff(obj.RLim);
sepR=dr./3;
multiE=ceil(log(sepR)/log(10));
sepR=sepR.*10.^(1-multiE);
sepR=obj.SepList(find(sepR<obj.SepList,1)-1)./10.^(1-multiE);
sepNum=floor(dr./sepR);
obj.RTick=obj.RLim(1)+(0:sepNum).*sepR;
if obj.RTick(end)~=obj.RLim(2)
obj.RTick=[obj.RTick,obj.RLim];
end
end
obj.RLim(obj.RLim<obj.RLim(1))=[];
obj.RLim(obj.RLim>obj.RLim(2))=[];
XR=cos(tt').*(obj.RTick-obj.RLim(1))./diff(obj.RLim);XR=[XR;nan([1,length(obj.RTick)])];
YR=sin(tt').*(obj.RTick-obj.RLim(1))./diff(obj.RLim);YR=[YR;nan([1,length(obj.RTick)])];
obj.RTickHdl=plot(obj.ax,XR(:),YR(:),'Color',[200,200,200]./255,'LineWidth',1.1,'LineStyle','--');
% 绘制雷达图
for i=1:size(obj.XData,1)
XP=cos(tn).*(obj.XData(i,:)-obj.RLim(1))./diff(obj.RLim);
YP=sin(tn).*(obj.XData(i,:)-obj.RLim(1))./diff(obj.RLim);
obj.PatchHdlP(i)=patch(obj.ax,XP,YP,obj.BC(mod(i-1,size(obj.BC,1))+1,:),...
'EdgeColor',obj.BC(mod(i-1,size(obj.BC,1))+1,:),'FaceAlpha',.2,...
'LineWidth',1.8);
obj.PatchHdlL(i)=plot(obj.ax,[XP,XP(1)],[YP,YP(1)],...
'Color',obj.BC(mod(i-1,size(obj.BC,1))+1,:),'Marker','o',...
'LineWidth',1.8,'MarkerFaceColor',obj.BC(mod(i-1,size(obj.BC,1))+1,:));
switch obj.Type
case 'Line',set(obj.PatchHdlP(i),'Visible','off')
case 'Patch',set(obj.PatchHdlL(i),'Visible','off')
case 'Both'
end
end
% 绘制R标签文本
tnr=(tn(1)+tn(2))/2;
for i=1:length(obj.RTick)
obj.RLabelHdl(i)=text(obj.ax,cos(tnr).*(obj.RTick(i)-obj.RLim(1))./diff(obj.RLim),...
sin(tnr).*(obj.RTick(i)-obj.RLim(1))./diff(obj.RLim),...
sprintf('%.2f',obj.RTick(i)),'FontName','Arial','FontSize',11);
end
% 绘制属性标签
for i=1:obj.PropNum
obj.PropLabelHdl(i)=text(obj.ax,cos(tn(i)).*1.1,sin(tn(i)).*1.1,obj.PropName{
i},...
'FontSize',12,'HorizontalAlignment','center');
end
end
% =========================================================================
function obj=setBkg(obj,varargin)
set(obj.BkgHdl,varargin{
:})
end
function obj=setType(obj,Type)
obj.Type=Type;
for i=1:size(obj.XData,1)
set(obj.PatchHdlP(i),'Visible','on')
set(obj.PatchHdlL(i),'Visible','on')
switch obj.Type
case 'Line',set(obj.PatchHdlP(i),'Visible','off')
case 'Patch',set(obj.PatchHdlL(i),'Visible','off')
end
end
delete(findobj('Tag','SRClagend'))
if isequal(obj.Type,'Line')
obj.LgdHdl=legend(obj.ax,[obj.PatchHdlL],obj.ClassName,'FontSize',12,'Location','best','Tag','SRClagend');
else
obj.LgdHdl=legend(obj.ax,[obj.PatchHdlP],obj.ClassName,'FontSize',12,'Location','best','Tag','SRClagend');
end
end
% 绘制图例
function obj=legend(obj)
if isequal(obj.Type,'Line')
obj.LgdHdl=legend(obj.ax,[obj.PatchHdlL],obj.ClassName,'FontSize',12,'Location','best','Tag','SRClagend');
else
obj.LgdHdl=legend(obj.ax,[obj.PatchHdlP],obj.ClassName,'FontSize',12,'Location','best','Tag','SRClagend');
end
end
% 设置图例属性
function obj=setLegend(obj,varargin)
set(obj.LgdHdl,varargin{
:})
end
% 设置标签
function obj=setPropLabel(obj,varargin)
for i=1:obj.PropNum
set(obj.PropLabelHdl(i),varargin{
:})
end
end
function obj=setRLabel(obj,varargin)
for i=1:length(obj.RLabelHdl)
set(obj.RLabelHdl(i),varargin{
:})
end
end
% 设置轴
function obj=setRTick(obj,varargin)
set(obj.RTickHdl,varargin{
:})
end
function obj=setThetaTick(obj,varargin)
set(obj.ThetaTickHdl,varargin{
:})
end
% 设置patch属性
function obj=setPatchN(obj,N,varargin)
switch obj.Type
case 'Line',set(obj.PatchHdlL(N),varargin{
:})
case 'Patch',set(obj.PatchHdlP(N),varargin{
:})
end
end
function setData(obj,Data)
tn=linspace(0,2*pi,obj.PropNum+1);tn=tn(1:end-1);
obj.XData=Data;
for i=1:size(obj.XData,1)
XP=cos(tn).*(obj.XData(i,:)-obj.RLim(1))./diff(obj.RLim);
YP=sin(tn).*(obj.XData(i,:)-obj.RLim(1))./diff(obj.RLim);
set(obj.PatchHdlL(i),'XData',[XP,XP(1)],'YData',[YP,YP(1)]);
set(obj.PatchHdlP(i),'XData',[XP,XP(1)],'YData',[YP,YP(1)]);
end
end
end
% @author : slandarer
% gzh : slandarer随笔
% -------------------------------------------------------------------------
end
Updated on March 19, 2023
Already supports the use of app designer, provide an example:
classdef radarChartApp < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
ButtonGroup matlab.ui.container.ButtonGroup
Button_3 matlab.ui.control.RadioButton
Button_2 matlab.ui.control.RadioButton
Button matlab.ui.control.Button
UIAxes matlab.ui.control.UIAxes
end
properties (Access = private)
Data=randi([-3,8],[4,7])+rand([4,7]); % Description
RC
end
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
app.RC=radarChart(app.UIAxes,app.Data);
app.RC.RLim=[-5,10];
app.RC.RTick=[-5,2,8:1:10];
app.RC=app.RC.draw();
app.RC=app.RC.legend();
end
% Button pushed function: Button
function ButtonPushed(app, event)
app.Data=randi([-3,8],[4,7])+rand([4,7]);
app.RC.setData(app.Data);
end
% Selection changed function: ButtonGroup
function ButtonGroupSelectionChanged(app, event)
selectedButton = app.ButtonGroup.SelectedObject;
switch selectedButton.Text
case '填充',app.RC.setType('Patch')
case '线条',app.RC.setType('Line')
end
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure and hide until all components are created
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Position = [100 100 640 480];
app.UIFigure.Name = 'MATLAB App';
% Create UIAxes
app.UIAxes = uiaxes(app.UIFigure);
title(app.UIAxes, 'Title')
xlabel(app.UIAxes, 'X')
ylabel(app.UIAxes, 'Y')
zlabel(app.UIAxes, 'Z')
app.UIAxes.Position = [1 21 446 441];
% Create Button
app.Button = uibutton(app.UIFigure, 'push');
app.Button.ButtonPushedFcn = createCallbackFcn(app, @ButtonPushed, true);
app.Button.BackgroundColor = [0 0.4471 0.7412];
app.Button.FontName = '宋体';
app.Button.FontSize = 24;
app.Button.FontWeight = 'bold';
app.Button.FontColor = [1 1 1];
app.Button.Position = [488 380 113 71];
app.Button.Text = {
'生成随机'; '数并绘图'};
% Create ButtonGroup
app.ButtonGroup = uibuttongroup(app.UIFigure);
app.ButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @ButtonGroupSelectionChanged, true);
app.ButtonGroup.Title = '雷达图类型';
app.ButtonGroup.FontName = '宋体';
app.ButtonGroup.FontSize = 18;
app.ButtonGroup.Position = [488 235 123 120];
% Create Button_2
app.Button_2 = uiradiobutton(app.ButtonGroup);
app.Button_2.Text = '线条';
app.Button_2.FontName = '宋体';
app.Button_2.FontSize = 14;
app.Button_2.Position = [11 49 58 22];
app.Button_2.Value = true;
% Create Button_3
app.Button_3 = uiradiobutton(app.ButtonGroup);
app.Button_3.Text = '填充';
app.Button_3.FontName = '宋体';
app.Button_3.FontSize = 14;
app.Button_3.Position = [11 21 65 22];
% Show the figure after all components are created
app.UIFigure.Visible = 'on';
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = radarChartApp
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end