📄 brushscatter.m
字号:
if ~isempty(H.Hbrush)
% Delete the current brush.
delete(H.Hbrush)
end
H.Hbrush = line('xdata',nan,'ydata',nan,'parent',gca,'visible','off',...
'erasemode','xor',...
'color','r','linewidth',2,'buttondown','brushscatter(''BrushButtDwn'')');
% Somethig like the following.
point1 = get(gca,'CurrentPoint'); % button down detected
finalRect = rbbox; % return figure units
point2 = get(gca,'CurrentPoint'); % button up detected
point1 = point1(1,1:2); % extract x and y
point2 = point2(1,1:2);
p1 = min(point1,point2); % calculate locations
offset = abs(point1-point2); % and dimensions
xx = [p1(1) p1(1)+offset(1) p1(1)+offset(1) p1(1) p1(1)];
yy = [p1(2) p1(2) p1(2)+offset(2) p1(2)+offset(2) p1(2)];
set(H.Hbrush,'xdata',xx,'ydata',yy,'visible','on','parent',gca)
H.BrushPrevX = [];
H.BrushPrevY = [];
% Highlight the points inside the brush.
UpdateHighlight(H)
set(tg,'userdata',H)
%%%%%%%%%% movebrushbuttup %%%%%%%%%%%%%%%%%%%%%%%%%%
function movebrushbuttup
% Reset the window functions.
tg = findobj('tag','brushscatter');
H = get(tg,'userdata'); % userdata for this gui.
% Reset the windows functions.
set(H.fig,'WindowButtonMotionFcn','')
set(H.fig,'WindowButtonUpFcn','')
set(H.fig,'Pointer','arrow')
%%%%%% MoveBrush %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function MoveBrush
% get handle
tg = findobj('tag','brushscatter');
H = get(tg,'userdata');
% The brush is in motion. Update the location of the brush.
% Then call the UpdateFunction.
if ishandle(H.Hbrush)
Hax = get(H.Hbrush,'parent');
cp = get(Hax,'CurrentPoint');
if isempty(H.BrushPrevX);
H.BrushPrevX = cp(1,1);
H.BrushPrevY = cp(1,2);
else
% Update brush position.
delx = cp(1,1) - H.BrushPrevX;
dely = cp(1,2) - H.BrushPrevY;
H.BrushPrevX = cp(1,1);
H.BrushPrevY = cp(1,2);
x = get(H.Hbrush,'xdata');
y = get(H.Hbrush,'ydata');
newx = x + delx;
newy = y + dely;
set(H.Hbrush,'xdata',newx,'ydata',newy);
end
% Call the update function to highlight points in the brush.
UpdateHighlight(H)
end
set(H.fig,'userdata',H)
%%%%%% UpdateHighlight %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function UpdateHighlight(H)
% First find the current axes.
Hcax = gca;
% H.mode contains the mode.
if strcmp(H.mode,'transient')
%%%%%%%%%% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
% NEED TO MAKE SURE THAT I HAVE SOMETHING THAT HAS THIS TAG.
hndls = findobj('tag','high');
delete(hndls)
end
% In this sub-function - highlight the points according to the mode that is
% specified: transient, lasting, undo
% Get the vertices of the brush.
if ~isempty(H.Hbrush)
xv = get(H.Hbrush,'xdata');
yv = get(H.Hbrush,'ydata');
else
return
end
% Find the two dimensions plotted there.
[I,J] = find(Hcax == H.Haxes); % Gives the indices to the current axes
XX = H.data(:,H.IndX(I,J)); % Get the corresponding X and Y coordinates.
YY = H.data(:,H.IndY(I,J));
[n,p] = size(H.data);
% Find the points inside the rectangle.
insidebrush = find(inpolygon(XX,YY,xv,yv));
outsidebrush = setdiff(1:n,insidebrush);
switch H.mode
case 'transient'
% Find all of the points that are in the polygon given by the
% brush. Should be able to do this for all plots with data.
% Make those inside the brush red - those outside black.
if ~isempty(insidebrush)
% need to loop through all of the plots and find the x and y
% values plotted there.
for ii = 1:length(H.highlight)
% find all of the highlighted ones and delete them.
Hhigh = line('xdata',nan,'ydata',nan,...
'markersize',3,'marker','o','linestyle','none',...
'tag','high'); % Placeholder for highlighted points.
% reset to the correct axes.
set(Hhigh,'parent',H.highlight(ii));
% Find the children - both lines - need to get to the
% actual data.
Hline = findobj(H.highlight(ii),'tag','black');
Xp = get(Hline,'xdata');
Yp = get(Hline,'ydata');
% plot highlighted points
set(Hhigh,'xdata',Xp(insidebrush),...
'ydata',Yp(insidebrush),...
'markerfacecolor',H.color);
end
end % if isempty
case 'lasting'
% Once points are brushed, they stay brushed. Just take the inside
% points and make them red. Those outside stay the same.
% For scatterplots, we will find the old red data values and add
% the inside ones to the old ones. Make them red.
if ~isempty(insidebrush)
% Scatterplot ones first.
for ii = 1:length(H.highlight)
% Find original data.
Hline = findobj(H.highlight(ii),'tag','black');
Xp = get(Hline,'xdata'); % This is the full data set.
Yp = get(Hline,'ydata');
% Now find ones already highlighted this color in this axes.
Hhigh = findobj('tag','high');
Hchild = get(H.highlight(ii),'children');
Hint = intersect(Hhigh,Hchild);
Hhigh = findobj(Hint,'markerfacecolor',H.color);
if isempty(Hhigh)
% Then set up new line with that color.
Ht = line('xdata',Xp(insidebrush),'ydata',Yp(insidebrush),...
'markersize',3,'marker','o','linestyle','none',...
'tag','high',...
'markerfacecolor',H.color); % Placeholder for highlighted points.
set(Ht,'parent',H.highlight(ii));
else
% Just augment the previous ones.
Xphigh = get(Hhigh,'xdata');
Yphigh = get(Hhigh,'ydata'); % plot highlighted points
Xpnew = Xp(insidebrush);
Ypnew = Yp(insidebrush);
try
xt = [Xpnew(:); Xphigh(:)];
yt = [Ypnew(:); Yphigh(:)];
catch
keyboard
end
obs = unique([xt,yt],'rows');
% Merge the sets and plot as highlighted.
% plot highlighted points
set(Hhigh,'xdata',obs(:,1),...
'ydata',obs(:,2),...
'markerfacecolor',H.color);
end
end
end % if isempty
case 'undo'
% Once points are brushed, are turned black.
if ~isempty(insidebrush)
% Scatterplot ones first.
for ii = 1:length(H.highlight)
% Find original data.
Hline = findobj(H.highlight(ii),'tag','black');
Xp = get(Hline,'xdata'); % This is the full data set.
Yp = get(Hline,'ydata');
% These are highlighted points - inside brush.
Xpin = Xp(insidebrush);
Ypin = Yp(insidebrush);
obsin = [Xpin(:) Ypin(:)];
% Now find all lines already highlighted on this axes.
Hhigh = findobj(H.highlight(ii),'tag','high');
% Loop through all of these in case there are points with
% more than one color inside the brush.
for jj = 1:length(Hhigh)
Xphigh = get(Hhigh(jj),'xdata');
Yphigh = get(Hhigh(jj),'ydata');
col = get(Hhigh(jj),'markerfacecolor');
obshigh = [Xphigh(:) Yphigh(:)];
obsleft = setdiff(obshigh, obsin,'rows');
% Merge the sets and plot as highlighted.
% plot highlighted points
set(Hhigh(jj),'xdata',obsleft(:,1),...
'ydata',obsleft(:,2),...
'markerfacecolor',col);
end
end
end % if isempty
end
%%%%%%%%%%%%%%%%%%%%%% INITIALIZE SCATTERPLOT %%%%%%%%%%%%%%%%%%%%%%%
function init(X,labs)
% Calling the function with the data.
% then initialize figure
H.data = X;
H.labs = labs;
% Set up figure that is maximized.
H.fig = figure('units','normalized',...
'position', [0 0.0365 0.9678 0.8750],...
'toolbar','none',...
'menubar','none',...
'numbertitle','off',...
'Name','Scatterplot Brushing: Right-click on diagonal square for menu of options. Left-click and drag on any scatterplot to create a brush.',...
'RendererMode','manual',...
'backingstore','off',...
'renderer','painters',...
'DoubleBuffer','on',...
'tag','brushscatter');
% Set up handle for context menu associated with axes.
H.cmenu = uicontextmenu;
H.MenHigh = uimenu(H.cmenu,'Label','Change Color',...
'callback','brushscatter(''color'')'); % Default brushing mode.
% H.MenDel = uimenu(H.cmenu,'Label','Delete',...
% 'checked','off',...
% 'callback','');
% 'callback','brushscatter(''delete'')');
H.operation = 'highlight';
% Above are the operations. Below are the modes.
% These callbacks should not activate anything.
% They should re-set a MODE FLAG and check/uncheck the item.
% They MOVE BRUSH code will check to see what is
% selected here.
H.MenTrans = uimenu(H.cmenu,'Label','Transient',...
'separator','on',...
'checked','on',...
'callback','brushscatter(''transient'')');
H.MenLast = uimenu(H.cmenu,'Label','Lasting',...
'checked','off',...
'callback','brushscatter(''lasting'')');
H.MenUndo = uimenu(H.cmenu,'Label','Undo',...
'checked','off',...
'callback','brushscatter(''undo'')');
H.mode = 'transient';
H.MenBrushOff = uimenu(H.cmenu,'Label','Delete Brush',...
'separator','on',...
'callback','brushscatter(''delbrush'')');
H.MenResetFig = uimenu(H.cmenu,'Label','Reset Figure',...
'separator','on',...
'callback','brushscatter(''resetfig'')');
[n,p] = size(X);
minx = min(X);
maxx = max(X);
rngx = range(X);
% set up the axes
H.IndX = zeros(p,p); % X dim for data
H.IndY = zeros(p,p); % Y dim for data
H.AxesLims = cell(p,p); % Axes limits.
H.Haxes = zeros(p,p); % Axes handles.
H.HlineHigh = zeros(p,p); % Line handles to highlighted data.
H.HlineReg = zeros(p,p); % Line handles to non-highlighted data.
H.Inside = []; % Indices to currently marked points. Need this for lasting mode.
% Order of axes is left-right, top-bottom
% Take up the entire figure area with axes.
I = 0; J = 0;
for j = (p-1):-1:0
I = I + 1;
for i = 0:(p-1)
J = J + 1;
pos = [i/p j/p 1/p 1/p];
pos = floor(pos*100)/100;
H.Haxes(I,J) = axes('pos',[i/p j/p 1/p 1/p]);
box on
if I~=J
% The following is the column index (to data) for the X and Y
% variables.
H.IndX(I,J) = J;
H.IndY(I,J) = I;
% Do the scatterplot.
Hline = plot(X(:,J),X(:,I),'ko');
set(gca,'yticklabel','','xticklabel','','ticklength',[0 0],...
'buttondownfcn','brushscatter(''createbrush'')',...
'drawmode','fast')
% This is for brushing/linking.
% Default color and 'undo' color is black!
% Non-highlighted data will have a tag of 'black'
set(Hline,'markersize',3,'marker','o','linestyle','none',...
'markerfacecolor','w',...
'tag','black')
% NOTE: one handle per line. Access color of individual points by
% the 'xdata' and 'ydata' indices.
ax = axis;
axis([ax(1)-rngx(J)*.05 ax(2)*1.05 ax(3)-rngx(I)*.05 ax(4)*1.05])
H.AxesLims{I,J} = axis;
axis manual
else
set(gca,'uicontextmenu',H.cmenu,...
'Yticklabel','','xticklabel','',...
'ticklength',[0 0])
% This is a center axes - plot the variable name.
text(0.35,0.45,labs{I})
text(0.05,0.05,num2str(minx(I)))
text(0.9,0.9,num2str(maxx(I)))
axis([0 1 0 1])
H.AxesLims{I,J} = [0 1 0 1];
end % if stmt
end % for j loop
J = 0;
end % for i loop
% Brush Information.
H.Hbrush = [];
H.BrushPrevX = [];
H.BrushPrevY = [];
H.CurrAxes = H.Haxes(1);
% Save all of the highlight-able axes in a vector.
[I,J] = size(H.Haxes);
k = 0;
for i = 1:I
for j = 1:J
if i ~= j
k = k + 1;
H.highlight(k) = H.Haxes(i,j);
end
end
end
% Set the color to red.
H.color = [1 0 0];
set(H.fig,'UserData',H)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -