MATLAB | Comment étiqueter automatiquement les points de dispersion hors plage lors du dessin d'un nuage de points ?

Cet article explique comment étiqueter automatiquement des points au-delà de la plage de la zone de coordonnées, par exemple :

La croix rouge à droite de la figure représente l'ordonnée du point dont l'abscisse dépasse la plage
, et bien entendu la croix rouge en dessous représente l'abscisse du point dont l'ordonnée dépasse la plage.

Les fonctions d'outil auto-écrites utilisées dans cet article scatterOORseront placées à la fin de l'article. Permettez-moi de parler d'abord de la façon de les utiliser.

utilisation de base

Supposons que vous écriviez le code suivant pour dessiner un nuage de points :

clc; clear; close all
rng(1)
% 生成随机点(Generate random points)
mu = [2 3; 6 7; 8 9];
S  = cat(3,[1 0; 0 2],[1 0; 0 2],[1 0; 0 1]);
r1 = abs(mvnrnd(mu(1,:),S(:,:,1),100));
r2 = abs(mvnrnd(mu(2,:),S(:,:,2),100));
r3 = abs(mvnrnd(mu(3,:),S(:,:,3),100));
% 绘制散点图(Draw scatter chart)
hold on
propCell = {
    
    'LineWidth',1.2,'MarkerEdgeColor',[.3,.3,.3],'SizeData',60};
scatter(r1(:,1),r1(:,2),'filled','CData',[0.40 0.76 0.60],propCell{
    
    :});
scatter(r2(:,1),r2(:,2),'filled','CData',[0.99 0.55 0.38],propCell{
    
    :});
scatter(r3(:,1),r3(:,2),'filled','CData',[0.55 0.63 0.80],propCell{
    
    :});
% 增添图例(Draw legend)
lgd = legend('scatter1','scatter2','scatter3');
lgd.Location = 'northwest';
lgd.FontSize = 14;
% 坐标区域基础修饰(Axes basic decoration)
ax=gca; grid on
ax.FontName   = 'Cambria';
ax.Color      = [0.9,0.9,0.9];
ax.Box        = 'off';
ax.TickDir    = 'out';
ax.GridColor  = [1 1 1];
ax.GridAlpha  = 1;
ax.LineWidth  = 1;
ax.XColor     = [0.2,0.2,0.2];
ax.YColor     = [0.2,0.2,0.2];
ax.TickLength = [0.015 0.025];
% 隐藏轴线(Hide XY-Ruler)
pause(1e-6)
ax.XRuler.Axle.LineStyle = 'none';
ax.YRuler.Axle.LineStyle = 'none';


ax.XLim = [-2,10];
ax.YLim = [2,14];

On ajoute directement une ligne à la fin du code :

scatterOOR()

ou

scatterOOR(gca)

Autrement dit, le premier paramètre est l'objet de zone de coordonnées, qui peut être omis. Des appels directs et simples peuvent produire les effets suivants :

Qu'en est-il des points fantaisie pour les pointillés hors limites ? Cela peut être réalisé en personnalisant scatterles propriétés graphiques, comme les deux méthodes suivantes :

scatterOOR('filled','CData',[0,0,.8],'LineWidth',1.5,...
    'MarkerEdgeColor',[.5,.5,.5],'SizeData',120,'Marker','s')
scatterOOR(gca,'filled','CData',[0,0,.8],'LineWidth',1.5,...
    'MarkerEdgeColor',[.5,.5,.5],'SizeData',120,'Marker','s')

On peut remarquer que le nom de légende par défaut du point hors limites est OOR, comment changer ce nom ?

C'est aussi très simple. Par exemple, pour changer le nom en LALALA, vous pouvez ajouter ces deux lignes à la fin du code :

OORHdl = findobj(ax,'Tag','SLANOOR');
OORHdl.DisplayName = 'LALALA';

Code complet de la fonction de l'outil

Très court, moins de 40 lignes :

function scatterOOR(ax,varargin)
% Copyright (c) 2023, Zhaoxu Liu / slandarer
if nargin < 1
    ax = gca;
end
if ~isa(ax,'matlab.graphics.axis.Axes')  
    varargin = [{
    
    ax}, varargin(:)'];
    ax = gca;
end
ax.NextPlot = 'add';
if isempty(varargin)
    varargin={
    
    'filled','CData',[.8,0,0],'LineWidth',1.5,...
    'MarkerEdgeColor',[.8,0,0],'SizeData',120,'Marker','x'};
end

OORHdl = findobj(ax,'Tag','SLANOOR');
if isempty(OORHdl)
    OORHdl = scatter([],[],varargin{
    
    :},'Tag','SLANOOR','DisplayName','OOR');
end
fullHdl = findobj(ax,'Type','scatter');
fullXData = [fullHdl(:).XData];
fullYData = [fullHdl(:).YData];

moveAxes();
addlistener(ax,'MarkedClean',@moveAxes);
    function moveAxes(~,~)
        tBool = fullXData >= ax.XLim(2) | fullXData <= ax.XLim(1)...
              | fullYData >= ax.YLim(2) | fullYData <= ax.YLim(1);
        tFullXData = fullXData; 
        tFullYData = fullYData;
        tFullXData(tFullXData >= ax.XLim(2)) = ax.XLim(2);
        tFullXData(tFullXData <= ax.XLim(1)) = ax.XLim(1);
        tFullYData(tFullYData >= ax.YLim(2)) = ax.YLim(2);
        tFullYData(tFullYData <= ax.YLim(1)) = ax.YLim(1);
        tFullXData = tFullXData(tBool);
        tFullYData = tFullYData(tBool);
        OORHdl.XData = tFullXData;
        OORHdl.YData = tFullYData;
    end
end

Je suppose que tu aimes

Origine blog.csdn.net/slandarer/article/details/131833062
conseillé
Classement