MATLAB | 绘图复刻(九) | 泰勒图及组合泰勒图

news2024/11/24 18:48:41

有粉丝问我这个图咋画:

我一看,这不就泰勒图嘛,就fileexchange上搜了一下泰勒图绘制代码,但是有的代码比较新的版本运行要改很多地方,有的代码需要包含一些压缩包没并没有的别人写的函数,于是我干脆自己写了个工具,想着如果大家用其他泰勒图绘制代码来不及修改的话,有多一次尝试机会吧。

复刻效果:

其他使用效果:

本文将分为大约四个部分:

  • 1 讲解泰勒图原理
  • 2 我写的工具函数基础使用教程
  • 3 属性修饰教程
  • 4 绘图复刻
  • 5 工具函数完整代码

1 泰勒图原理

泰勒图是Karl E. Taylor于2001年首先提出,主要用来比较几个气象模式模拟的能力,因此该表示方法在气象领域使用最多,但是在其他自然科学领域也有一定的应用。

这个图巧妙地利用了相关系数(COR)、均方根误差(RMSE/RMSD)和标准差(STD)三个评价指标之间的关系,巧妙地将三个变量的数据安排在了二维图上。

讲解一下公式和关系哈,为了避免误会后文中各个评价指标均用首字母代写( C , R , S C,R,S C,R,S),参考"标尺"使用小写字母 r r r,当前观察对象使用小写字母 f f f

标准差

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

均方根误差

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

相关系数

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

余弦关系

就是很简单的差的平方展开式 ( a − b ) 2 = a 2 + b 2 − 2 a b (a-b)^2=a^2+b^2-2ab (ab)2=a2+b22ab,很容易能看出来:

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

那我们如果把 C C C 看成 cos ⁡ ( θ ) \cos(\theta) cos(θ) 这不就余弦公式嘛,因此可以将其安排在一个图中:

就可以同时看出两组数据的各种统计量的相近程度。


2 我写的工具函数使用教程

2.1 数据预处理

数据首先要与标准数据对比计算标准差、中心均方根误差、相关系数,使用SStats函数,该函数会放在文末。

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 axes(生成泰勒图坐标区域)
TD = STaylorDiag(STATS);

2.3 绘制散点

使用SPlot函数绘制,大概像下面这样(TD.SPlot),改形状就改Marker属性即可:

% 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 添加图例

添加图例并标注标准数据组(使用SText函数):

% 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 标注每个点

循环使用SText函数即可:

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 属性修饰

统一使用set函数进行修改,大概这么用:

  • TD.set(对象名, 属性名, 属性值,…)

对象名就是由各个评价指标首字母( C , R , S C,R,S C,R,S)以及这个玩意的MATLAB内常用名称组合而成的,例如标准差轴就是SAxis,相关系数网格就是CGrid

3.1 基础属性

那些刻度长度啊,各个轴范围呀啥的要最先修饰。例如刻度长度:

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

各个轴范围:

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

主刻度及次刻度值:

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 网格属性

设置网格粗细及颜色:

% 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 标签属性

修饰轴标签及刻度标签:

% 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 轴属性

设置轴颜色、粗细:

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

3.5 刻度属性

刻度粗细、颜色、线型啥的都能设置:

% 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 绘图复刻

4.1 数据说明

没去找原始论文数据,这里随便用了组数据且四个坐标区域用的数据也一样,到时候大家可自行更换:

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 子图创建

硬创建呗:

%% 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 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 绘制散点

最后一组散点绘制后对象被存到lgdPltHdl的矩阵,这是为了之后生成图例方便(只显示第2-6组数据的图例,不显示标准数据):

%% 绘制散点
% 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 添加图例和标注

% 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 工具函数完整代码

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.
        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);
            tRMSD = sqrt(2.*(obj.STATS(1,1).^2)-2.*(obj.STATS(1,1).^2).*obj.CTickValues);
            tTRMSD = asin(tRMSD./2./obj.STATS(1,1)).*2;
            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];
            tRMSDM = sqrt(2.*(obj.STATS(1,1).^2)-2.*(obj.STATS(1,1).^2).*obj.CMinorTickValues);
            tTRMSDM = asin(tRMSDM./2./obj.STATS(1,1)).*2;
            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 = 2.*asin(RMSD./2./STD);
            pltHdl = plot(obj.ax,cos(tTheta).*STD,sin(tTheta).*STD,varargin{:},'LineStyle','none');
        end
        function txtHdl=SText(obj,STD,RMSD,~,varargin)
            tTheta = 2.*asin(RMSD./2./STD);
            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
end

未经允许本代码请勿作商业用途,引用的话可以引用我file exchange上的链接,可使用如下格式:

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

若转载请保留以上file exchange链接及本文链接!!!!!

本文全部代码已同时上传gitee仓库,可从gitee或者fileexchange下载:

https://gitee.com/slandarer/PLTreprint

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/635647.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA-八种基础数据类型和包装类型及相关面试题

文章目录 前言一、基本数据类型1.1 分类1.2 概念1.3 代码1.4 二维表 二、各基本数据类型间强制转换2.1 为什么Java中有强制转换&#xff1f;2.2 示例代码 三、包装类型3.1 为什么有包装类型&#xff1f;3.2 基本概念3.3 转换方法 四、转换过程中使用的自动装箱和自动拆箱4.1 来…

Redis Lua脚本原理

Lua脚本执行过程 创建并修改Lua环境 1 创建基础Lua环境2 载入函数库3 创建全局表格Lua4 替换随机函数5 创建排序辅助函数6 创建redis.pcall函数7 全局环境保护8 修改后的Lua环境保存到服务器状态的Lua属性&#xff0c;等待脚本执行 Redis中带有不确定性的命令&#xff1a; …

RK3588平台开发系列讲解(以太网篇)PHY状态机

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、PHY状态机定义二、PHY的状态变化三、PHY的状态变化打印沉淀、分享、成长,让自己和他人都能有所收获!😄 一、PHY状态机定义 phy状态机: 目录:include/linux/phy.h enum phy_state {PHY_DOWN = 0,</

开源模型的力量

2 月&#xff0c;Meta 发布了其大型语言模型&#xff1a;LLaMA。与 OpenAI 及其 ChatGPT 不同&#xff0c;Meta 不仅仅为世界提供了一个可以玩的聊天窗口。 相反&#xff0c;它将代码发布到开源社区&#xff0c;此后不久模型本身就被泄露了。研究人员和程序员立即开始修改、改…

Protobuf实战:通讯录

网络版通讯录 需求 Protobuf常⽤于通讯协议、服务端数据交换场景。接下来将实现⼀个⽹络版本的通讯录&#xff0c;模拟实现客⼾端与服务端的交互&#xff0c;通过Protobuf来实现各端之间的协议序列化。 需求如下&#xff1a; 客⼾端可以选择对通讯录进⾏以下操作&#xff1a;…

电子科技大学编译原理复习笔记(七):自下而上语法分析

目录 前言 重点一览 引言 自下而上分析 分析方法 规范规约&#xff08;最左规约&#xff0c;对应最右推导&#xff09; 算符优先分析法 算符优先文法 最左素短语 举个例子 优先关系表的构造 规范规约与算符优先分析 LR分析法 概述 LR&#xff08;0&#xff09…

系统架构设计师 2:计算机基础

一、计算机硬件 1 处理器&#xff08;CPU&#xff09; 处理器是计算机系统运算和控制的核心部件。 1.1 指令集 处理器的指令集按照其复杂程度可分为复杂指令集&#xff08;CISC&#xff09;与精简指令集&#xff08;RISC&#xff09;。 随着研究的深入&#xff0c;RISC已经…

基于深度学习的高精度安全背心检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度安全背心检测识别系统可用于日常生活中或野外来检测与定位安全背心目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的安全背心目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5…

2.25 sigprocmask函数使用 2.26sigaction信号捕捉函数 2.27SIGCHILD信号

2.25 sigprocmask函数使用 阻塞信号集有时称作信号掩码。 联想&#xff1a;fcntl函数可以修改fd属性。 ./sigprocmask & //将程序设置为后台运行&#xff0c;输入ls可以同步有输出 fg //将程序恢复到前台运行#include <stdio.h> #include <signal.…

动态规划dp —— 21.乘积最大子数组

1.状态表示 是什么&#xff1f;dp表中里的值所表示的含义就是状态表示 因为要考虑负数情况&#xff0c;负数乘以最大数就等于最小数了&#xff0c;负数乘以最小数就是最大数了 f[i]表示&#xff1a;以i位置为结尾的所以子数组中最大乘积 g[i]表会&#xff1a;以i位置为结尾…

Java 实现删除顺序表中第一次出现的某个元素

一、思路 1.顺序表不能是空的&#xff0c;如果顺序表是空的就肯定无法删除第一次出现的 key 元素. 2.定义一个key变量来传入要删除的元素&#xff0c;这个元素要求是第一次出现的. 3.删除之前要先找到第一次出现的key的下标. 4.找到位置之后就开始删除. 5.删除过程是从key下标位…

Linux - struct file与缓冲区

​​​​​​​ ​​​​​​​ 感谢各位 点赞 收藏 评论 三连支持 本文章收录于专栏【Linux系统编程】 ❀希望能对大家有所帮助❀ 本文章由 风君子吖 原创 ​​​​​​​ ​​​​​​​ ​​​​​​​ 前言 对于文件&#x…

DTS迁移Oracle至DM与MySQL至DM

目录 DTS迁移Oracle至DM... 3 一、前期准备... 3 二、DTS迁移... 4 1、新建工程... 5 2、新建迁移... 6 3、填写源库信息&#xff0c;使用指定驱动并自定义URL连接... 7 4、填写目标库信息... 8 5、填写迁移选项... 8 6、指定迁移模式及模式对象... 9 7、执行迁移...…

http长连接与会话保持

"我们半推半就的人生&#xff0c;没有和你一样被眷顾的未来!" 一、Http长连接 (1) 为什么需要长连接 如上展示的是一个常规得并不能再常规的http服务&#xff0c;从本地拉取远端linux上的本地文件上传至浏览器上&#xff0c;经过浏览器的渲染展示成如今的样子。唔&a…

【实战】体验训练Geneface

一.环境 conda activate geneface export PYTHONPATH./ CUDA_VISIBLE_DEVICES0 python tasks/run.py --configegs/datasets/lrs3/lm3d_syncnet.yaml --exp_namelrs3/syncnet 训练这篇出过的一些奇奇怪怪的问题基本上都记录在【环境搭建】40系一些奇奇怪怪的环境问题_weixin_50…

aigc - 文化衫设计

团队要用aigc设计个文化衫&#xff0c;就是给些提示词&#xff0c;然后让ai自动生成能够包含这些提示词的文化衫出来 二、第二版 思路&#xff1a;收集了30多张文化衫&#xff0c;然后用两种方式生成提升词&#xff1a;一个是自然语言描述这件t-short&#xff0c;一个是全名词…

IDEA常用插件Top18

前言&#xff1a;精心推荐给大家的一些日常开发中最常用的IDEA效率插件。 1、Alibaba Java Coding Guidelines代码规范检查工具 Alibaba Java Coding Guidelines ,阿里的一款强大的代码规范检查工具&#xff0c;可以让自己写出易读性更高的代码&#xff0c;可以让团队代码风格…

Keepalived+LVS

这里写目录标题 一、Keepalived及其工作原理1.1Keepalived体系主要模块及其作用1.3VRRP &#xff08;虚拟路由冗余协议&#xff09; 二、keepalived实验部署主服务器&#xff1a;备用服务器配置节点 一配置节点二 三、测试 一、Keepalived及其工作原理 Keepalived 是一个基于V…

Linux编译器 gcc、g++

绪论 你热爱生命吗&#xff1f;那幺别浪费时间&#xff0c;由于时间是组成生命的材料。——富兰克林 。 本篇文章写了主要写了Linux下编译器&#xff0c;以及编译器是如何实现编译的过程。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 附&…

2.30 守护进程(1) 2.31 守护进程(2)

2.30 守护进程&#xff08;1&#xff09; 终端 echo $$//查看当前终端的的pid tty//查看当前终端设备控制终端可以操作某一个进程。 进程组 会话 进程组、会话、控制终端之间的关系 find/2 查看2重定向到dev/null设备上&#xff0c;|管道&#xff08;创建子进程&#xff09…