MATLAB | How to use MATLAB to draw a radar chart (spider chart)

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 Patchtwo Linestyles, Typeset 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 setBkga 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 Patchobjects and Lineobjects respectively. The decoration methods are slightly different, but they are all setPatchNdecorated 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:

insert image description here

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

Guess you like

Origin blog.csdn.net/slandarer/article/details/126982513