MATLAB: Move a scatter3 3D point around using a GUI slider

scatter3slider

Hello,
I placed a 3D point near a surface using scatter3 (in Matlab2012a), and would like to add a slider that can move that point around. I see an example for 2015a that uses updateSystem, but I don't seem to have that: http://www.mathworks.com/help/control/ug/build-app-with-interactive-plot-updates.html
I believe it should be do-able in 2012a…
Here's the code I have so far that makes the surface, and plots a few scatter3 points. It's the point with s= that I would like to move around. I managed only to place 2 sliders so far on the GUI. The plan is to hook slider b up to r, and slider b1 up to x. Hopefully then scatter3 point s moves around.
echo OFF ALL;
f = figure;
[X,Y,Z] = sphere(200);
Z(Z < 0.0) = NaN;
X(X < 0.0) = NaN;
Y(Y < 0.0) = NaN;
quarterSphere = surf(X,Y,Z);
set(quarterSphere,'FaceColor',[0 0 0],'FaceAlpha',0.3,'EdgeColor',[0 0 0],'EdgeAlpha',0.1);
hold on;
% sample calc to place a point on the 1/4 sphere, in any location
r = 0.99; % radius in a plane to get y for a given x, where x <= r
x = 0.1; % x distance within r circle
if x > r
% h = msgbox('x must be <= r');
error('x must be <= r');
end
y=sqrt(r^2-x^2);
z=sqrt(1-x^2-y^2);
s = scatter3(x,y,z,50,[1 0 0],'filled');
scatter3(.5,.5,.5,50,[0 0 0],'filled'); % NPI
scatter3(.6,.8,.2,50,[0 1 0],'filled'); % high Vavg, low CTI
scatter3(.6,.2,.8,50,[0 1 0],'filled'); % low Vavg, high CTI
scatter3(.8,.6,.2,50,[1 1 0],'filled'); % high density, low CTI
scatter3(.2,.6,.8,50,[1 1 0],'filled'); % low density, high CTI
scatter3(.8,.2,.6,50,[0 1 1],'filled'); % high density, low Vavg
scatter3(.2,.8,.6,50,[0 1 1],'filled'); % low density, high Vavg
hold off;
xlabel('density');
ylabel('Vavg');
zlabel('CTI');
view([1 0 0]);
axis square;
b = uicontrol('Parent',f,'Style','slider','units','normalized','Position',[0,.005,.5,.01],'value',x, 'min',0, 'max',1);
blabel = uicontrol('Parent',f,'Style','text','string','r','units','normalized','Position',[0.25,.015,.02,.03]);
b1 = uicontrol('Parent',f,'Style','slider','units','normalized','Position',[.5,.005,.5,.01],'value',x, 'min',0, 'max',1);
b1label = uicontrol('Parent',f,'Style','text','string','x','units','normalized','Position',[0.75,.015,.02,.03]);

Best Answer

David - you need to assign a callback to each of your sliders. Try the following - wrap all of your above code in a function block so that you can nest a local function within it. Something like
function myFunction
echo OFF ALL;
f = figure;
[X,Y,Z] = sphere(200);
Z(Z < 0.0) = NaN;
X(X < 0.0) = NaN;
Y(Y < 0.0) = NaN;
% etc.
end
Now assign a callback to each of your sliders as
b = uicontrol('Parent',f,'Style','slider','units','normalized',...
'Position', [0,.005,.5,.01],'value',r, 'min',0, 'max',1, ...
'Callback', {@update3DPointS});
blabel = uicontrol('Parent',f,'Style','text','string','r',...
'units','normalized','Position',[0.25,.015,.02,.03]);
b1 = uicontrol('Parent',f,'Style','slider','units','normalized',...
'Position', [.5,.005,.5,.01],'value',x, 'min',0, 'max',1, ...
'Callback', {@update3DPointS});
b1label = uicontrol('Parent',f,'Style','text','string','x','units', ...
'normalized','Position',[0.75,.015,.02,.03]);
Now nest your callback within the main function block as
function update3DPointS(~,~)
r = get(b,'Value');
x = get(b1, 'Value');
y=sqrt(r^2-x^2);
z=sqrt(1-x^2-y^2);
set(s,'XData',x,'YData',y,'ZData',z);
end
Now run your code and see what happens. Whenever you press one of the arrows at either end of either slider, then the red dot will update its position. See the attached code for an example.