MATLAB | Drawing reproduction (9) | Taylor diagram and combined Taylor diagram

A fan asked me how I drew this picture:

I saw that this is not a Taylor diagram, so I searched for the Taylor diagram drawing code on fileexchange, but some codes need to be changed a lot when running in a newer version, and some codes need to contain some compressed packages that are not written by others. function, so I simply wrote a tool myself, thinking that if you use other Taylor diagram drawing codes and it is too late to modify, you will have one more chance to try.

Replica effect:

Other effects:

This article will be divided into roughly four parts:

  • 1 Explain the principle of Taylor diagram
  • 2 The basic usage tutorial of the utility function written by me
  • 3 Attribute Modification Tutorial
  • 4 Drawing reproduction
  • 5 The complete code of the tool function

1 Principle of Taylor diagram

The Taylor diagram was first proposed by Karl E. Taylor in 2001. It is mainly used to compare the simulation capabilities of several meteorological models. Therefore, this representation method is most used in the meteorological field, but it also has certain applications in other natural science fields.

This figure cleverly uses the relationship between the three evaluation indicators of correlation coefficient (COR), root mean square error (RMSE/RMSD) and standard deviation (STD), and arranges the data of the three variables in a two-dimensional graph superior.

Explain the formula and relationship. In order to avoid misunderstanding, each evaluation index in the article is written with the first letter ( C , R , SC, R, SC,R,S ), refer to "ruler" using lowercaserrr , the current observation object uses the lowercase letterfff

standard deviation

S r = ∑ n = 1 N ( r n − r ˉ ) 2 N S f = ∑ n = 1 N ( f n − f ˉ ) 2 N \begin{aligned} &S_r = \sqrt{\frac{\sum_{n = 1}^{N}(r_n-\bar{r})^2}{N}}\\ &S_f = \sqrt{\frac{\sum_{n = 1}^{N}(f_n-\bar{f})^2}{N}} \end{aligned} Sr=Nn=1N(rnrˉ)2 Sf=Nn=1N(fnfˉ)2

root mean square error

R = ∑ n = 1 N ( ( f n − f ˉ ) − ( r n − r ˉ ) ) 2 N R = \sqrt{\frac{\sum_{n = 1}^{N}((f_n-\bar{f})-(r_n-\bar{r}))^2}{N}} R=Nn=1N((fnfˉ)(rnrˉ))2

correlation coefficient

C = ∑ n = 1 N ( f n − f ˉ ) ( r n − r ˉ ) N S r S f C = \frac{\sum_{n = 1}^{N}(f_n-\bar{f})(r_n-\bar{r})}{NS_rS_f} C=NSrSfn=1N(fnfˉ)(rnrˉ)

cosine relationship

It is a very simple square expansion of the difference ( a − b ) 2 = a 2 + b 2 − 2 ab (ab)^2=a^2+b^2-2ab(ab)2=a2+b22 ab , it is easy to see that:

R 2 = S r 2 + S f 2 − 2 S r S f C R^2=S_r^2+S_f^2-2S_rS_fC R2=Sr2+Sf22SrSfC

Then if we put CCC coefficient⁡ ( θ ) \cos(\theta)cos ( θ ) is not just the cosine formula, so it can be arranged in a graph:

You can see the similarity of various statistics of the two sets of data at the same time.


2 The utility function tutorial I wrote

2.1 Data preprocessing

The data must first be compared with the standard data to calculate the standard deviation, center root mean square error, and correlation coefficient, and use SStatsa function, which will be placed at the end of the article.

clc; clear
Data = load('testData.mat');
Data = Data.Data(:,1:end-1);

% Calculate STD RMSD and COR(计算标准差、中心均方根误差、相关系数)
STATS = zeros(4,size(Data,2));
for i = 1:size(Data,2)
    STATS(:,i) = SStats(Data(:,1),Data(:,i));
end
STATS(1,:) = [];

2.2 Create Taylor diagram coordinate area

% Create taylor axes(生成泰勒图坐标区域)
TD = STaylorDiag(STATS);

2.3 Drawing scatter points

Use the SPlot function to draw, probably like the following (TD.SPlot), just change the Marker property to change the shape:

% Color list(颜色列表)
colorList = [0.3569    0.0784    0.0784
    0.6784    0.4471    0.1725
    0.1020    0.3882    0.5176
    0.1725    0.4196    0.4392
    0.2824    0.2275    0.2902];
MarkerType={
    
    'o','diamond','pentagram','^','v'};
% Plot(绘制散点图)
for i = 1:size(Data,2)
    TD.SPlot(STATS(1,i),STATS(2,i),STATS(3,i),'Marker',MarkerType{
    
    i},'MarkerSize',15,...
        'Color',colorList(i,:),'MarkerFaceColor',colorList(i,:));
end

2.4 Add legend

Add a legend and label the standard data set (using the SText function):

% Legend
NameList = {
    
    'AAA','BBB','CCC','DDD','EEE'};
legend(NameList,'FontSize',13,'FontName','Times New Roman')

% Annotation
TD.SText(STATS(1,1),STATS(2,1),STATS(3,1),{
    
    'reference';' '},'FontWeight','bold',...
    'FontSize',20,'FontName','Times New Roman','Color',colorList(1,:),...
    'VerticalAlignment','bottom','HorizontalAlignment','center')

2.5 Label each point

Just use the SText function in a loop:

for i = 1:size(Data,2)
    TD.SText(STATS(1,i),STATS(2,i),STATS(3,i),"   "+string(NameList{
    
    i}),'FontWeight','bold',...
    'FontSize',14,'FontName','Times New Roman',...
    'VerticalAlignment','middle','HorizontalAlignment','left')
end


3 attribute modification

Use the set function uniformly to modify, probably like this:

  • TD.set(object name, property name, property value,…)

The object name is composed of the initial letters of each evaluation index ( C , R , SC,R,SC,R,S ) and the commonly used names in MATLAB for this thing, for example, the standard deviation axis is SAxis, and the correlation coefficient grid is CGrid

3.1 Basic attributes

Those scale lengths, the range of each axis and so on should be modified first. For example tick length:

TD.set('TickLength',[.015,.05])

Each axis range:

TD.set('SLim',[0,300])
TD.set('RLim',[0,175])

Major scale and minor scale values:

TD.set('STickValues',0:50:300)
TD.set('SMinorTickValues',0:25:300)
TD.set('RTickValues',0:25:175)
TD.set('CTickValues',[.1,.2,.3,.4,.5,.6,.7,.8,.9,.95,.99])

3.2 Grid properties

Set grid thickness and color:

% Set Grid(修饰各个网格)
TD.set('SGrid','Color',[.7,.7,.7],'LineWidth',1.5)
TD.set('RGrid','Color',[.77,.6,.18],'LineWidth',1.5)
TD.set('CGrid','Color',[0,0,.8],'LineStyle',':','LineWidth',.8);

3.3 Label properties

Decorate axis labels and tick labels:

% Set Tick Label(修饰刻度标签)
TD.set('STickLabelX','Color',[.8,0,0],'FontWeight','bold')
TD.set('STickLabelY','Color',[.8,0,0],'FontWeight','bold')
TD.set('RTickLabel','Color',[.77,.6,.18],'FontWeight','bold')
TD.set('CTickLabel','Color',[0,0,.8],'FontWeight','bold')

% Set Label(修饰标签)
TD.set('SLabel','Color',[.8,0,0],'FontWeight','bold')
TD.set('CLabel','Color',[0,0,.8],'FontWeight','bold')

3.4 Axis Properties

Set axis color, thickness:

% Set Axis(修饰各个轴)
TD.set('SAxis','Color',[.8,0,0],'LineWidth',2)
TD.set('CAxis','Color',[0,0,.8],'LineWidth',2)

3.5 Scale properties

Scale thickness, color, line type and so on can be set:

% Set Tick and MinorTick(修饰主次刻度)
TD.set('STick','Color',[.8,0,0],'LineWidth',8)
TD.set('CTick','Color',[0,0,.8],'LineWidth',8)
TD.set('SMinorTick','Color',[.8,0,0],'LineWidth',5)
TD.set('CMinorTick','Color',[0,0,.8],'LineWidth',5)


4 Drawing reproduction

4.1 Data Description

I didn’t find the original paper data, so I used the group data casually here and the data used in the four coordinate areas are the same, and you can replace it by yourself at that time:

clc; clear
Data = load('testData.mat');
Data = Data.Data;
% % 不想下数据的可以用随便捏造的数据试试
% % 随便捏造了点数据(Made up some data casually)
% Data = randn(100,6).*.2+[(linspace(-1,.5,100)').*ones(1,2),...
%                          (linspace(-.5,.7,100)').*ones(1,2),...
%                          (linspace(-.9,.2,100)').*ones(1,2)];

% Calculate STD RMSD and COR(计算标准差、中心均方根误差、相关系数)
STATS = zeros(4,size(Data,2));
for i = 1:size(Data,2)
    STATS(:,i) = SStats(Data(:,1),Data(:,i));
end
STATS(1,:) = [];

4.2 Subgraph Creation

Hard to create chant:

%% Create figure and axes(生成基础布局)
fig=figure('Units','normalized','Position',[.2,.1,.54,.74]);
bkgAx=axes(fig,'Position',[.13,.11,.67,.88],'XTick',[],'YTick',[],'Box','on',...
    'Color',[253,228,203]./255,'XLim',[0,100],'YLim',[0,88],'NextPlot','add');
plot(bkgAx,[50,50],[0,88],'Color','k','LineWidth',.8)
text(bkgAx,25,42,'Autumn','FontSize',16,'FontName','Times New Roman','HorizontalAlignment','center')
text(bkgAx,75,42,'Winter','FontSize',16,'FontName','Times New Roman','HorizontalAlignment','center')
text(bkgAx,25,86,'Spring','FontSize',16,'FontName','Times New Roman','HorizontalAlignment','center')
text(bkgAx,75,86,'Summer','FontSize',16,'FontName','Times New Roman','HorizontalAlignment','center')
bkgAx.XLabel.String='Standard Deviation(mm month^{-1})';
bkgAx.XLabel.FontSize=18;
bkgAx.XLabel.FontName='Times New Roman';
bkgAx.XLabel.Position=[50,-3,-1];
bkgAx.YLabel.String='Standard Deviation(mm month^{-1})';
bkgAx.YLabel.FontSize=18;
bkgAx.YLabel.FontName='Times New Roman';
bkgAx.YLabel.Position=[-7,44,-1];
% -------------------------------------------------------------------------
ax1 = axes(fig,'Position',[.13,.11,.335,.4],'Box','on');
ax2 = axes(fig,'Position',[.465,.11,.335,.4],'Box','on');
ax3 = axes(fig,'Position',[.13,.55,.335,.4],'Box','on');
ax4 = axes(fig,'Position',[.465,.55,.335,.4],'Box','on');

4.3 Create a Taylor diagram coordinate area

You can replace the first parameter with a coordinate area object, and you can modify the specific coordinate area into a Taylor diagram coordinate area. The following is the point attribute adjustment after generation:

%% Create taylor axes(生成泰勒图坐标区域)
TD1 = STaylorDiag(ax1,STATS);
set(ax1,'Box','on','XTick',[],'YTick',[],'XColor','k','YColor','k',...
    'XLim',TD1.SLim.*1.13,'YLim',TD1.SLim.*1.15);
TD1.set('SLabel','Color','none');
TD1.set('RGrid','Color',[.77,.6,.18],'LineWidth',1.2)
TD1.set('RTickLabel','Color',[.77,.6,.18],'FontWeight','bold')
TD1.set('CLabel','FontSize',16)

TD2 = STaylorDiag(ax2,STATS);
set(ax2,'Box','on','XTick',[],'YTick',[],'XColor','k','YColor','k',...
    'XLim',TD2.SLim.*1.13,'YLim',TD2.SLim.*1.15);
TD2.set('SLabel','Color','none');
TD2.set('STickLabelY','Color','none');
TD2.set('RGrid','Color',[.77,.6,.18],'LineWidth',1.2)
TD2.set('RTickLabel','Color',[.77,.6,.18],'FontWeight','bold')
TD2.set('CLabel','FontSize',16)

TD3 = STaylorDiag(ax3,STATS);
set(ax3,'Box','on','XTick',[],'YTick',[],'XColor','k','YColor','k',...
    'XLim',TD2.SLim.*1.13,'YLim',TD2.SLim.*1.15);
TD3.set('SLabel','Color','none');
TD3.set('STickLabelX','Color','none');
TD3.set('RGrid','Color',[.77,.6,.18],'LineWidth',1.2)
TD3.set('RTickLabel','Color',[.77,.6,.18],'FontWeight','bold')
TD3.set('CLabel','FontSize',16)

TD4 = STaylorDiag(ax4,STATS);
set(ax4,'Box','on','XTick',[],'YTick',[],'XColor','k','YColor','k',...
    'XLim',TD2.SLim.*1.13,'YLim',TD2.SLim.*1.15);
TD4.set('SLabel','Color','none');
TD4.set('STickLabelX','Color','none');
TD4.set('STickLabelY','Color','none');
TD4.set('RGrid','Color',[.77,.6,.18],'LineWidth',1.2)
TD4.set('RTickLabel','Color',[.77,.6,.18],'FontWeight','bold')
TD4.set('CLabel','FontSize',16)


4.4 Drawing scatter points

After the last group of scatter plots, the objects are stored in the matrix of lgdPltHdl, which is for the convenience of generating legends later (only the legends of the 2-6 groups of data are displayed, and the standard data is not displayed):

%% 绘制散点
% Color list(颜色列表)
colorList = [145,81,155;217,34,30;68,127,183;76,181,75;145,81,155;248,130,7]./255;
% Plot(绘制散点图)
for i = 1:size(Data,2)
    TD1.SPlot(STATS(1,i),STATS(2,i),STATS(3,i),'Marker','o','MarkerSize',10,...
        'Color',colorList(i,:),'MarkerFaceColor',colorList(i,:));
    TD2.SPlot(STATS(1,i),STATS(2,i),STATS(3,i),'Marker','o','MarkerSize',10,...
        'Color',colorList(i,:),'MarkerFaceColor',colorList(i,:));
    TD3.SPlot(STATS(1,i),STATS(2,i),STATS(3,i),'Marker','o','MarkerSize',10,...
        'Color',colorList(i,:),'MarkerFaceColor',colorList(i,:));
    lgdPltHdl(i)=TD4.SPlot(STATS(1,i),STATS(2,i),STATS(3,i),'Marker','o','MarkerSize',10,...
        'Color',colorList(i,:),'MarkerFaceColor',colorList(i,:));
end


4.5 Add legend and label

% legend
lgdHdl = legend(ax4,lgdPltHdl(2:end),{
    
    '# 1 1/x','# 2 e\^-x(x/0.1\^2)','# 3 e\^-x(x/0.5\^2)','# 4 e\^-x(x/0.2\^2)','# 5 e\^-x(x/0.25\^2)'},...
    'Position',[.825,.47,0.15,0.2]);
lgdHdl.Title.String='Weighting Scheme';
lgdHdl.Title.FontSize=14;
lgdHdl.Title.FontName='Times New Roman';
lgdHdl.FontSize=12;
lgdHdl.FontName='Times New Roman';
lgdHdl.Box='off';
% Annotation
TD1.SText(STATS(1,1),STATS(2,1),STATS(3,1),{
    
    'observed';''},'FontWeight','bold',...
    'FontSize',13,'FontName','Times New Roman','Color',colorList(1,:),...
    'VerticalAlignment','bottom','HorizontalAlignment','center');
TD2.SText(STATS(1,1),STATS(2,1),STATS(3,1),{
    
    'observed';''},'FontWeight','bold',...
    'FontSize',13,'FontName','Times New Roman','Color',colorList(1,:),...
    'VerticalAlignment','bottom','HorizontalAlignment','center');
TD3.SText(STATS(1,1),STATS(2,1),STATS(3,1),{
    
    'observed';''},'FontWeight','bold',...
    'FontSize',13,'FontName','Times New Roman','Color',colorList(1,:),...
    'VerticalAlignment','bottom','HorizontalAlignment','center');
TD4.SText(STATS(1,1),STATS(2,1),STATS(3,1),{
    
    'observed';''},'FontWeight','bold',...
    'FontSize',13,'FontName','Times New Roman','Color',colorList(1,:),...
    'VerticalAlignment','bottom','HorizontalAlignment','center');
text(ax1,TD1.SLim(2),TD1.SLim(2),'RMS error','Color',[.77,.6,.18],...
    'VerticalAlignment','bottom','HorizontalAlignment','right',...
    'FontSize',15,'FontName','Times New Roman','FontWeight','bold')
text(ax2,TD1.SLim(2),TD1.SLim(2),'RMS error','Color',[.77,.6,.18],...
    'VerticalAlignment','bottom','HorizontalAlignment','right',...
    'FontSize',15,'FontName','Times New Roman','FontWeight','bold')
text(ax3,TD1.SLim(2),TD1.SLim(2),'RMS error','Color',[.77,.6,.18],...
    'VerticalAlignment','bottom','HorizontalAlignment','right',...
    'FontSize',15,'FontName','Times New Roman','FontWeight','bold')
text(ax4,TD1.SLim(2),TD1.SLim(2),'RMS error','Color',[.77,.6,.18],...
    'VerticalAlignment','bottom','HorizontalAlignment','right',...
    'FontSize',15,'FontName','Times New Roman','FontWeight','bold')


5 The complete code of the tool function

5.1 SStats

function Data=SStats(Cr,Cf)
% Copyright (c) 2023, Zhaoxu Liu / slandarer
% Zhaoxu Liu / slandarer (2023). taylor diagram class 
% (https://www.mathworks.com/matlabcentral/fileexchange/130889-taylor-diagram-class), 
% MATLAB Central File Exchange.
Cr = Cr(:); 
Cf = Cf(:);
nanInd = isnan(Cr)|isnan(Cf);
Cr(nanInd) = [];
Cf(nanInd) = [];

% N  = length(Cf);
MEAN = mean(Cf);
STD  = std(Cf,1);
RMSD = std(Cf-Cr,1);
COR  = corrcoef(Cf,Cr);
Data = [MEAN, STD, RMSD, COR(1,2)].';

%% calculation formula of STD RMSD and COR
% N = length(Cf);
%
% 		    /  sum[ {C-mean(C)} .^2]  \
% STD = sqrt|  ---------------------  |
% 		    \          N              /
%
% Equivalent calculation formula:
% STD = sqrt(sum((Cf-mean(Cf)).^2)./N);
% STD = norm(Cf-mean(Cf))./sqrt(N);
% STD = rms(Cf-mean(Cf));
% STD = sqrt(var(Cf,1));
% STD = std(Cf,1);
  

% 		     /  sum[  { [C-mean(C)] - [Cr-mean(Cr)] }.^2  ]  \
% RMSD = sqrt|  -------------------------------------------  |
% 		     \                      N                        /
% 
% Equivalent calculation formula:
% RMSD = sqrt(sum((Cf-mean(Cf)-(Cr-mean(Cr))).^2)./N);
% RMSD = norm(Cf-mean(Cf)-Cr+mean(Cr))./sqrt(N);
% RMSD = rmse(Cr-mean(Cr),Cf-mean(Cf));
% RMSD = rms(Cf-mean(Cf)-Cr+mean(Cr));
% RMSD = sqrt(var(Cf-Cr,1));
% RMSD = std(Cf-Cr,1);


% 		sum( [C-mean(C)].*[Cr-mean(Cr)] ) 
% COR = --------------------------------- 
% 		         N*STD(C)*STD(Cr)
%
% Equivalent calculation formula:
% COR = sum((Cf-mean(Cf)).*(Cr-mean(Cr)))./N./std(Cf,1)./std(Cr,1);
% COR = (Cf-mean(Cf)).'*(Cr-mean(Cr))./N./std(Cf,1)./std(Cr,1);
% COR = [1,0]*cov(Cf,Cr,1)./std(Cf,1)./std(Cr,1)*[0;1];
% COR = [1,0]*corrcoef(Cf,Cr)*[0;1];
end

5.2 STaylorDiag

classdef STaylorDiag < handle
% Copyright (c) 2023, Zhaoxu Liu / slandarer
% Zhaoxu Liu / slandarer (2023). taylor diagram class 
% (https://www.mathworks.com/matlabcentral/fileexchange/130889-taylor-diagram-class), 
% MATLAB Central File Exchange.
    properties
        STATS;  % STD RMSD and COR
        ax; TickLength=[.015,.008];
        % S-Axis means STD Axis
        SAxis; RAxis; CAxis;
        SGrid; RGrid; CGrid;
        SLabel; RLabel; CLabel;   
        STickLabelX; STickLabelY; RTickLabel; CTickLabel;
        % STD Tick and MinorTick
        STick; SMinorTick; STickValues; SMinorTickValues; SLim;
        %
        RTickValues; RLim;
        %
        CTick; CMinorTick; CLim = [0,1];
        CTickValues=[.1,.3,.5,.7,.9,.95,.99];
        CMinorTickValues=[.05,.15,.2,.25,.35,.4,.45,.55,.6,.65,.75,.8,.85,.91,.92,.93,.94,.96,.97,.98,1]; 
    end
    methods
        function obj = STaylorDiag(varargin)
            if isa(varargin{
    
    1},'matlab.graphics.axis.Axes')
                obj.ax = varargin{
    
    1}; varargin(1) = [];
            else
                obj.ax = gca;
            end
            obj.STATS = varargin{
    
    1};
            obj.ax.Parent.Color = [1,1,1];
            obj.ax.NextPlot = 'add';
            obj.ax.XGrid = 'off';
            obj.ax.YGrid = 'off';
            obj.ax.Box = 'off';
            obj.ax.DataAspectRatio = [1,1,1];
            % -------------------------------------------------------------
            obj.SLim = [0,max(obj.STATS(1,:)).*1.15];
            obj.ax.XLim = obj.SLim;
            obj.STickValues = obj.ax.XTick;
            obj.RLim = [0,max(obj.STATS(2,:)).*1.15];
            obj.ax.XLim = obj.RLim;
            obj.RTickValues = obj.ax.XTick;
            obj.RTickValues(1) = [];
            obj.ax.XLim = obj.SLim; obj.ax.YLim = obj.SLim;
            obj.SMinorTickValues = ...
                linspace(obj.STickValues(1),obj.STickValues(end),(length(obj.STickValues)-1).*5+1);
            obj.SMinorTickValues=setdiff(obj.SMinorTickValues,obj.STickValues);
            obj.CMinorTickValues=setdiff(obj.CMinorTickValues,obj.CTickValues);
            % -------------------------------------------------------------
            % STD Tick, MinorTick, Grid, TickLabel
            [tYTickX,tYTickY,tYTickMX,tYTickMY,tRGridX,tRGridY] = obj.getSValue();
            obj.SGrid = plot(obj.ax,tRGridX(:),tRGridY(:),'LineWidth',.5,'Color','k');
            obj.SAxis = plot(obj.ax,[0,0,obj.SLim(2)],[obj.SLim(2),0,0],'LineWidth',1.2,'Color','k');
            obj.STick = plot(obj.ax,[tYTickX(:);tYTickY(:)],[tYTickY(:);tYTickX(:)],'LineWidth',.8,'Color','k');
            obj.SMinorTick = plot(obj.ax,[tYTickMX(:);tYTickMY(:)],[tYTickMY(:);tYTickMX(:)],'LineWidth',.8,'Color','k');
            obj.STickLabelX = text(obj.ax,obj.STickValues,0.*obj.STickValues,string(obj.STickValues),...
                'FontName','Times New Roman','FontSize',13,'VerticalAlignment','top','HorizontalAlignment','center');
            obj.STickLabelY = text(obj.ax,0.*obj.STickValues(2:end),obj.STickValues(2:end),string(obj.STickValues(2:end))+" ",...
                'FontName','Times New Roman','FontSize',13,'VerticalAlignment','middle','HorizontalAlignment','right');
            obj.SLabel = text(obj.ax,obj.ax.YLabel.Position(1),obj.ax.YLabel.Position(2),'Standard Deviation',...
                'FontName','Times New Roman','FontSize',20,'VerticalAlignment','bottom','HorizontalAlignment','center','Rotation',90);
            obj.SGrid.Annotation.LegendInformation.IconDisplayStyle='off';
            obj.SAxis.Annotation.LegendInformation.IconDisplayStyle='off';
            obj.STick.Annotation.LegendInformation.IconDisplayStyle='off';
            obj.SMinorTick.Annotation.LegendInformation.IconDisplayStyle='off';
            % -------------------------------------------------------------
            % RMSD Grid TickLabel
            [tR2GridX,tR2GridY] = obj.getRValue();
            obj.RGrid = plot(obj.ax,tR2GridX(:),tR2GridY(:),'LineWidth',.5,'Color','k','LineStyle','--');
            obj.RTickLabel = text(obj.ax,cos(pi*5/6).*obj.RTickValues+obj.STATS(1,1),sin(pi*5/6).*obj.RTickValues,string(obj.RTickValues),...
                'FontName','Times New Roman','FontSize',13,'VerticalAlignment','bottom','HorizontalAlignment','center','Rotation',60);
            obj.RGrid.Annotation.LegendInformation.IconDisplayStyle='off';
            % -------------------------------------------------------------
            % RMSD^2 = STD_r^2 + STD_f^2 - 2*STD_r*STD_f*COR
            %
            %        STD_r^2 + STD_f^2 - RMSD^2
            % COR = ----------------------------
            %              2*STD_r*STD_f
            %
            [tCAxisX,tCAxisY,tTRMSD,tCTickX,tCTickY,tCTickMX,tCTickMY,tRMSDGridX,tRMSDGridY]=obj.getCValue();
            obj.CGrid = plot(obj.ax,tRMSDGridX(:),tRMSDGridY(:),'LineWidth',.5,'Color',[.8,.8,.8],'LineStyle','-');
            obj.CAxis = plot(obj.ax,tCAxisX,tCAxisY,'LineWidth',1.2,'Color','k');
            obj.CTick = plot(obj.ax,tCTickX(:),tCTickY(:),'LineWidth',.8,'Color','k');
            obj.CMinorTick = plot(obj.ax,tCTickMX(:),tCTickMY(:),'LineWidth',.8,'Color','k');
            for i=1:length(tTRMSD)
                obj.CTickLabel{
    
    i} = text(obj.ax,cos(tTRMSD(i)).*obj.SLim(2),sin(tTRMSD(i)).*obj.SLim(2)," "+string(obj.CTickValues(i)),...
                    'FontName','Times New Roman','FontSize',13,'VerticalAlignment','middle','HorizontalAlignment','left','Rotation',tTRMSD(i)./pi.*2.*90);
            end
            obj.CLabel = text(obj.ax,cos(pi/4).*(obj.SLim(2)-obj.ax.YLabel.Position(1)),...
                sin(pi/4).*(obj.SLim(2)-obj.ax.YLabel.Position(1)),'Correlation',...
                'FontName','Times New Roman','FontSize',20,'VerticalAlignment','bottom','HorizontalAlignment','center','Rotation',-45);
            obj.CGrid.Annotation.LegendInformation.IconDisplayStyle='off';
            obj.CAxis.Annotation.LegendInformation.IconDisplayStyle='off';
            obj.CTick.Annotation.LegendInformation.IconDisplayStyle='off';
            obj.CMinorTick.Annotation.LegendInformation.IconDisplayStyle='off';
            % -------------------------------------------------------------
            obj.ax.XColor = 'none';
            obj.ax.YColor = 'none';
        end
        % =================================================================
        function [tYTickX,tYTickY,tYTickMX,tYTickMY,tRGridX,tRGridY]=getSValue(obj)
            tTPi_2 = linspace(0,pi/2,200).';
            tYTickX = [0.*obj.STickValues;obj.STickValues.*0+obj.TickLength(1).*obj.SLim(2);nan.*obj.STickValues];
            tYTickY = [obj.STickValues;obj.STickValues;nan.*obj.STickValues];
            tYTickMX = [0.*obj.SMinorTickValues;obj.SMinorTickValues.*0+obj.TickLength(2).*obj.SLim(2);nan.*obj.SMinorTickValues];
            tYTickMY = [obj.SMinorTickValues;obj.SMinorTickValues;nan.*obj.SMinorTickValues];
            tRGridX = [obj.STickValues.*cos(repmat(tTPi_2,[1,length(obj.STickValues)]));nan.*obj.STickValues];
            tRGridY = [obj.STickValues.*sin(repmat(tTPi_2,[1,length(obj.STickValues)]));nan.*obj.STickValues];
        end
        function [tR2GridX,tR2GridY]=getRValue(obj)
            tTPi = linspace(0,pi,200).';
            tR2GridX = [obj.RTickValues.*cos(repmat(tTPi,[1,length(obj.RTickValues)]));nan.*obj.RTickValues]+obj.STATS(1,1);
            tR2GridY = [obj.RTickValues.*sin(repmat(tTPi,[1,length(obj.RTickValues)]));nan.*obj.RTickValues];
            tR2GridN = sqrt(tR2GridX.^2+tR2GridY.^2)>obj.SLim(2);
            tR2GridX(tR2GridN) = nan; tR2GridY(tR2GridN) = nan;
        end
        function [tCAxisX,tCAxisY,tTRMSD,tCTickX,tCTickY,tCTickMX,tCTickMY,tRMSDGridX,tRMSDGridY]=getCValue(obj)
            tTPi_2 = linspace(0,pi/2,200).';
            tCAxisX = cos(tTPi_2).*obj.SLim(2);
            tCAxisY = sin(tTPi_2).*obj.SLim(2);
            tTRMSD = acos(obj.CTickValues);
            tCTickX = [cos(tTRMSD).*obj.SLim(2);cos(tTRMSD).*obj.SLim(2).*(1-obj.TickLength(1));tTRMSD.*nan];
            tCTickY = [sin(tTRMSD).*obj.SLim(2);sin(tTRMSD).*obj.SLim(2).*(1-obj.TickLength(1));tTRMSD.*nan];
            tTRMSDM = acos(obj.CMinorTickValues);
            tCTickMX = [cos(tTRMSDM).*obj.SLim(2);cos(tTRMSDM).*obj.SLim(2).*(1-obj.TickLength(2));tTRMSDM.*nan];
            tCTickMY = [sin(tTRMSDM).*obj.SLim(2);sin(tTRMSDM).*obj.SLim(2).*(1-obj.TickLength(2));tTRMSDM.*nan];
            tRMSDGridX = [cos(tTRMSD).*obj.SLim(2);0.*tTRMSD;nan.*tTRMSD];
            tRMSDGridY = [sin(tTRMSD).*obj.SLim(2);0.*tTRMSD;nan.*tTRMSD];
        end
        % =================================================================
        function pltHdl=SPlot(obj,STD,RMSD,~,varargin)
            tTheta = acos(-(RMSD.^2-STD.^2-obj.STATS(1,1).^2)./(2.*STD.*obj.STATS(1,1)));
            pltHdl = plot(obj.ax,cos(tTheta).*STD,sin(tTheta).*STD,varargin{
    
    :},'LineStyle','none');
        end
        function txtHdl=SText(obj,STD,RMSD,~,varargin)
            tTheta = acos(-(RMSD.^2-STD.^2-obj.STATS(1,1).^2)./(2.*STD.*obj.STATS(1,1)));
            txtHdl = text(obj.ax,cos(tTheta).*STD,sin(tTheta).*STD,varargin{
    
    :});
        end
        % =================================================================
        function set(obj,target,varargin)
            if isa(varargin{
    
    1},'char')||isa(varargin{
    
    1},'string')
            switch target
                case {
    
    'SAxis','CAxis','SLabel','CLabel','STick','CTick','SMinorTick','CMinorTick','RTickLabel','SGrid','RGrid','CGrid'}
                    set(obj.(target),varargin{
    
    :});
                case 'STickLabelX'
                    set(obj.STickLabelX,varargin{
    
    :});
                case 'STickLabelY'
                    set(obj.STickLabelY,varargin{
    
    :});
                case 'CTickLabel'
                    for i=1:length(obj.CTickLabel)
                        set(obj.CTickLabel{
    
    i},varargin{
    
    :});
                    end
            end
            else
                oriRLim = obj.RLim;
                obj.(target) = varargin{
    
    1};
                obj.ax.XColor = 'k';
                obj.ax.YColor = 'k';
                if abs(obj.SLim(2)-obj.ax.XLim(2))>eps||abs(obj.RLim(2)-oriRLim(2))>eps
                    obj.ax.XLim = obj.SLim;
                    obj.STickValues = obj.ax.XTick;
                    obj.ax.XLim = obj.RLim;
                    obj.RTickValues = obj.ax.XTick;
                    obj.RTickValues(1) = [];
                    obj.ax.XLim = obj.SLim; obj.ax.YLim = obj.SLim;
                    obj.SMinorTickValues = ...
                        linspace(obj.STickValues(1),obj.STickValues(end),(length(obj.STickValues)-1).*5+1);
                end
                obj.(target) = varargin{
    
    1};
                obj.SMinorTickValues=setdiff(obj.SMinorTickValues,obj.STickValues);
                obj.CMinorTickValues=setdiff(obj.CMinorTickValues,obj.CTickValues);        
                %
                [tYTickX,tYTickY,tYTickMX,tYTickMY,tRGridX,tRGridY] = obj.getSValue();
                set(obj.SGrid,'XData',tRGridX(:),'YData',tRGridY(:));
                set(obj.SAxis,'XData',[0,0,obj.SLim(2)],'YData',[obj.SLim(2),0,0]);
                set(obj.STick,'XData',[tYTickX(:);tYTickY(:)],'YData',[tYTickY(:);tYTickX(:)]);
                set(obj.SMinorTick,'XData',[tYTickMX(:);tYTickMY(:)],'YData',[tYTickMY(:);tYTickMX(:)]);
                delete(obj.STickLabelX);delete(obj.STickLabelY);delete(obj.SLabel)
                obj.STickLabelX = text(obj.ax,obj.STickValues,0.*obj.STickValues,string(obj.STickValues),...
                    'FontName','Times New Roman','FontSize',13,'VerticalAlignment','top','HorizontalAlignment','center');
                obj.STickLabelY = text(obj.ax,0.*obj.STickValues(2:end),obj.STickValues(2:end),string(obj.STickValues(2:end))+" ",...
                    'FontName','Times New Roman','FontSize',13,'VerticalAlignment','middle','HorizontalAlignment','right');
                obj.SLabel = text(obj.ax,obj.ax.YLabel.Position(1),obj.ax.YLabel.Position(2),'Standard Deviation',...
                    'FontName','Times New Roman','FontSize',20,'VerticalAlignment','bottom','HorizontalAlignment','center','Rotation',90);
                %
                [tR2GridX,tR2GridY] = obj.getRValue();
                set(obj.RGrid,'XData',tR2GridX(:),'YData',tR2GridY(:));
                delete(obj.RTickLabel)
                obj.RTickLabel = text(obj.ax,cos(pi*5/6).*obj.RTickValues+obj.STATS(1,1),sin(pi*5/6).*obj.RTickValues,string(obj.RTickValues),...
                    'FontName','Times New Roman','FontSize',13,'VerticalAlignment','bottom','HorizontalAlignment','center','Rotation',60);
                %
                [tCAxisX,tCAxisY,tTRMSD,tCTickX,tCTickY,tCTickMX,tCTickMY,tRMSDGridX,tRMSDGridY]=obj.getCValue();
                set(obj.CGrid,'XData',tRMSDGridX(:),'YData',tRMSDGridY(:));
                set(obj.CAxis,'XData',tCAxisX,'YData',tCAxisY);
                set(obj.CTick,'XData',tCTickX(:),'YData',tCTickY(:));
                set(obj.CMinorTick,'XData',tCTickMX(:),'YData',tCTickMY(:));
                for i=length(obj.CTickLabel):-1:1
                    delete(obj.CTickLabel{
    
    i});
                end
                delete(obj.CLabel);
                for i=1:length(tTRMSD)
                    obj.CTickLabel{
    
    i} = text(obj.ax,cos(tTRMSD(i)).*obj.SLim(2),sin(tTRMSD(i)).*obj.SLim(2)," "+string(obj.CTickValues(i)),...
                        'FontName','Times New Roman','FontSize',13,'VerticalAlignment','middle','HorizontalAlignment','left','Rotation',tTRMSD(i)./pi.*2.*90);
                end
                obj.CLabel = text(obj.ax,cos(pi/4).*(obj.SLim(2)-obj.ax.YLabel.Position(1)),...
                    sin(pi/4).*(obj.SLim(2)-obj.ax.YLabel.Position(1)),'Correlation',...
                    'FontName','Times New Roman','FontSize',20,'VerticalAlignment','bottom','HorizontalAlignment','center','Rotation',-45);
                obj.ax.XColor = 'none';
                obj.ax.YColor = 'none';
            end
        end
    end
% Copyright (c) 2023, Zhaoxu Liu / slandarer
% Zhaoxu Liu / slandarer (2023). taylor diagram class 
% (https://www.mathworks.com/matlabcentral/fileexchange/130889-taylor-diagram-class), 
% MATLAB Central File Exchange.
end

over

Please do not use this code for commercial purposes without permission. If you quote it, you can quote the link on my file exchange. You can use the following format:

Zhaoxu Liu / slandarer (2023). taylor diagram class ( https://www.mathworks.com/matlabcentral/fileexchange/130889-taylor-diagram-class ), MATLAB Central File Exchange. Retrieved from 2023/6/11.

If you reprint, please keep the above file exchange link and this article link! ! ! ! !

All the codes in this article have been uploaded to the gitee warehouse at the same time, and can be downloaded from gitee or fileexchange:

https://gitee.com/slandarer/PLTreprint

Guess you like

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