-
Notifications
You must be signed in to change notification settings - Fork 5
/
textscatter.m
116 lines (104 loc) · 2.82 KB
/
textscatter.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
% plot scatter where text strings are used as markers into gca.
%
% INPUTS:
% xy: coordinates - can by xy or xyz in columns
% thand: cell array of strings
% colors: default [0 0 0]. If size(colors,1) matches numel(x) we plot each
% text string (and maybe marker) in the specified color.
% plotmarker: default false. If true, we plot a . at each x,y coordinate
% and shift the text labels over.
%
% OUTPUTS:
% thand: handles to text objects
% p: handles to markers
%
% [thand,p] = textscatter(xy,t,[colors],plotmarker)
function [thand,p] = textscatter(xy,t,colors,plotmarker)
% p may be left undefined if ~plotmarker
p = [];
% text fails in mysterious ways with single inputs
xy = double(xy);
% handle single char t inputs
if ischar(t)
t = {t};
end
switch numel(t)
case 1
% support plotting the same text label multiple times
t = repmat(t,[1,size(xy,1)]);
case size(xy,1)
% all good
otherwise
error('numel(t) does not match size(xy,1)');
end
% skip nans
nans = any(isnan(xy),2);
xy(nans,:) = [];
t(nans) = [];
n = size(xy,1);
% number of dimensions to plot over
nd = size(xy,2);
% track hold state
changedhold = false;
if ~ishold
hold on;
changedhold = true;
end
% if we are plotting a marker the text needs to shift away from center
if ieNotDefined('plotmarker')
plotmarker = false;
end
if plotmarker
halign = 'right';
valign = 'bottom';
% add space to clear the marker
t = cellfun(@(thist)[thist ' '],t,'uniformoutput',0);
else
halign = 'center';
valign = 'middle';
end
% handle 2D or 3D plots
switch nd
case 2
plotter = @(p,co)plot(p(:,1),p(:,2),'o','markerfacecolor',co,...
'markeredgecolor','none');
texter = @(p,t,co)text(p(:,1),p(:,2),t,'horizontalalignment',...
halign,'verticalalignment',valign,'color',co);
case 3
plotter = @(p,co)plot3(p(:,1),p(:,2),p(:,3),'o',...
'markerfacecolor',co,'markeredgecolor','none');
texter = @(p,t,co)text(p(:,1),p(:,2),p(:,3),t,...
'horizontalalignment',halign,'verticalalignment',valign,...
'color',co);
otherwise
error('unsupported input dimensionality: %d',nd);
end
if ieNotDefined('colors')
colors = [0 0 0];
elseif size(colors,1)>1
colors(nans,:) = [];
end
if ~plotmarker
% invisible plot to get axis limits set properly
p = plotter(xy,[1 1 1]);
set(p,'linestyle','none','marker','none');
end
if size(colors,1)==1
% one call will do
thand = texter(xy,t,colors);
if plotmarker
p = plotter(xy,colors);
end
else
for ind = 1:n
thand(ind) = texter(xy(ind,:),t(ind),colors(ind,:));
if plotmarker
p(ind) = plotter(xy(ind,:),colors(ind,:));
end
end
end
% we assume you want the text on top
uistack(thand,'top')
if changedhold
hold off;
end