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 scatterOOR
seront 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 scatter
les 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