I have a GUI, there I have some sliders and I want to change the R4 variable from callback.
I tried this(also, it works on edit buttons, but not on sliders):
%Function file
Slider2 = uicontrol('Style','slide',...
'Units','normalized',...
'Position',[0.65 0.71 0.15 0.05],...
'Min',1,'Max',100,'Value',R4,...
'Callback',['R4=','num2str(get(Slider2,''Value''))']); %I tried 'str2num(get(gco,''String''))' too, doesn't work. It's throwing this error: Warning: 'slider' control requires a scalar Value. //I kinda understand what he tries to say, but i don't know how to do it.
%display the value of the slider
uicontrol('Style','text',...
'Units','normalized',...
'BackgroundColor',[0.75,0.75,0.75],...
'Position',[0.80 0.70 0.05 0.05],...
'foregroundcolor','black',...
'String',num2str(get(Slider2,'Value')));
And the edit button:
uicontrol('Style','text',...
'Units','normalized',...
'BackgroundColor',[0.75,0.75,0.75],...
'ForegroundColor','black',...
'Position',[0.10 0.8 0.05 0.05],...
'String','R1 =');
ButEd1 = uicontrol('Style','edit',...
'Units','normalized',...
'BackgroundColor',[0.75,0.75,0.75],...
'ForegroundColor','black',...
'Position',[0.15 0.81 0.1 0.05],...
'String',R1,...
'Callback',['R1=','str2num(get(gco,''String''))']);
Update: now updates and displays variable value as well. It's indeed a bit tricky, you can find some helpful explanations here. How far-fetched is your homework supposed to be?
figure();
text=uicontrol('Style','text',...
'Units','normalized',...
'BackgroundColor',[0.75,0.75,0.75],...
'Position',[0.80 0.70 0.05 0.05],...
'foregroundcolor','black',...
'String','50');
R4=[];
update_text=#(x) set(text,'String',num2str(x));
update_var=#(x) assignin('base','R4',x);
disp_var=#(x) disp(x);
update_all=#(x) cellfun(#feval,{update_text,update_var,disp_var},x);
update_call=#(x,y,z) update_all({x.Value,x.Value,x.Value});
Slider2 = uicontrol('Style','slide',...
'Units','normalized',...
'Position',[0.65 0.71 0.15 0.05],...
'Min',1,'Max',100,'Value',50,...
'Callback',update_call);
=========original post===========
You should have found in the document (search for 'Slider') that the callback function is expected to receive 3 parameters, with the first being the calling object (i.e. 'self'). Things are pretty straight-forward from there.
figure();
text=uicontrol('Style','text',...
'Units','normalized',...
'BackgroundColor',[0.75,0.75,0.75],...
'Position',[0.80 0.70 0.05 0.05],...
'foregroundcolor','black',...
'String','50');
update_text=#(x,y,z) set(text,'String',num2str(x.Value));
Slider2 = uicontrol('Style','slide',...
'Units','normalized',...
'Position',[0.65 0.71 0.15 0.05],...
'Min',1,'Max',100,'Value',50,...
'Callback',update_text);
Related
Why is there a difference between
figure;
process = {'process' , [0.2500 0.5000], [0.6 0.8];
'process2', [0.1250 0.2500], [0.2 0.6];
'process3', [0.3125 0.2500], [0.4 0.6];
'process4', [0.2500 0.3125], [0.2 0.4];
'process5', [0.3750 0.3125], [0.2 0.4];
'process5', [0.5625 0.5000], [0.6 0.8];};
L=line(cell2mat(process(:,2)), cell2mat(process(:,3)));
and
figure;
process = {'process' , [0.2500 0.5000], [0.6 0.8];
'process2', [0.1250 0.2500], [0.2 0.6];
'process3', [0.3125 0.2500], [0.4 0.6];
'process4', [0.2500 0.3125], [0.2 0.4];
'process5', [0.3750 0.3125], [0.2 0.4];
'process5', [0.5625 0.5000], [0.6 0.8];};
hold on
L=line(cell2mat(process(1,2)), cell2mat(process(1,3)));
L=line(cell2mat(process(2,2)), cell2mat(process(2,3)));
L=line(cell2mat(process(3,2)), cell2mat(process(3,3)));
L=line(cell2mat(process(4,2)), cell2mat(process(4,3)));
L=line(cell2mat(process(5,2)), cell2mat(process(5,3)));
L=line(cell2mat(process(6,2)), cell2mat(process(6,3)));
?
Is there a way that enables me to use the first version (= using the line function only once) with the result of the second one?
As per the documentation for line:
line(X,Y) adds the line defined in vectors X and Y to the
current axes. If X and Y are matrices of the same size, line
draws one line per column.
So you want,
line(cell2mat(process(:,2))', cell2mat(process(:,3))');
I need code to pushbuttons "zoom in", "zoom out" for my image. Trying to used this but wrong. Please, help me. I work with the MATLAB Gui.
function btnZoomIn_Callback(hObject, eventdata, handles)
uicontrol('Style','pushbutton','String','ZoomIn','Units','pixels',...
'Position',[90 10 60 20],'Enable','off',...
'Tag','btnZoomIn','Callback',#btnZoomIn_Callback);
h = guihandles(hObject);
set(h.btnZoomOut,'Enable','on')
data = guidata(hObject);
data.magnif = data.magnif+1;
guidata(hObject, data)
function btnZoomOut_Callback(hObject, eventdata, handles)
uicontrol('Style','pushbutton','String','Zoom Out','Units','pixels',...
'Position',[160 10 60 20],'Enable','off',...
'Tag','btnZoomOut','Callback',#btnZoomOut_Callback);
h = guihandles(hObject);
data = guidata(hObject);
if data.magnif > 1
data.magnif = data.magnif-1;
if data.magnif == 1
If you want to be cheeky about it (hopefully that idiom translates...), you could just point your professor to the built-in zoom buttons.
A (non-GUIDE) example:
f = figure;
ax = axes('Parent', f, 'Units', 'Normalized', 'Position', [0.1 0.18 0.8 0.8]);
A = imread('ngc6543a.jpg'); % Read a built-in image as a sample
image(A, 'Parent', ax);
However, if you need a serious answer, see MATLAB's zoom function, which you can add to your button callbacks.
To expand on the above example:
f = figure;
ax = axes('Parent', f, 'Units', 'Normalized', 'Position', [0.1 0.18 0.8 0.8]);
A = imread('ngc6543a.jpg'); % Read a built-in image as a sample
image(A, 'Parent', ax);
zoomonbutton = uicontrol('Parent', f, ...
'Style', 'pushbutton', ...
'Units', 'Normalized', ...
'Position', [0.1 0.02 0.4 0.1], ...
'String', 'Zoom On', ...
'Callback', 'zoom on' ...
);
zoomoffbutton = uicontrol('Parent', f, ...
'Style', 'pushbutton', ...
'Units', 'Normalized', ...
'Position', [0.5 0.02 0.4 0.1], ...
'String', 'Zoom Off', ...
'Callback', 'zoom off' ...
);
Where pushing the 'on' button turns on Interactive Zooming. From the documentation:
zoom on turns on interactive zooming. When interactive zooming is
enabled in a figure, pressing a mouse button while your cursor is
within an axes zooms into the point or out from the point beneath the
mouse. Zooming changes the axes limits. When using zoom mode, you
Zoom in by positioning the mouse cursor where you want the center of the plot to be and either
Press the mouse button or
Rotate the mouse scroll wheel away from you (upward).
Zoom out by positioning the mouse cursor where you want the center of the plot to be and either
Simultaneously press Shift and the mouse button, or
Rotate the mouse scroll wheel toward you (downward).
And pushing the 'off' button turns off this interactive mode.
Hopefully this helps you in the right direction. I would recommend you investigate MATLAB's documentation, it's very comprehensive and has many examples.
My program creates 5 pushbuttons, and I need to change their color according to the values in a matrix A. So I define A in the main, and then at the end of main I call the function create_maze(A).
The following is create_maze(A):
function create_maze(A)
A
% create 5X5 pushbuttons
scr = get(0, 'screensize');
f1 = figure(1);
set(f1, 'menubar', 'none');
set(f1, 'position', [scr(1) scr(2) scr(3) scr(4)]);
h1 = uicontrol('Style', 'pushbutton',...
'ForegroundColor', 'blue',...
'Position', [200 200 100 100],...
'Callback', pushbutton1_Callback);
h2 = uicontrol('Style', 'pushbutton',...
'ForegroundColor', 'blue',...
'Position', [300 200 100 100],...
'Callback', pushbutton1_Callback);
h3 = uicontrol('Style', 'pushbutton',...
'ForegroundColor', 'blue',...
'Position', [400 200 100 100],...
'Callback', pushbutton1_Callback);
h4 = uicontrol('Style', 'pushbutton',...
'ForegroundColor', 'blue',...
'Position', [500 200 100 100],...
'Callback', pushbutton1_Callback);
h5 = uicontrol('Style', 'pushbutton',...
'ForegroundColor', 'blue',...
'Position', [600 200 100 100],...
'Callback', pushbutton1_Callback);
function [L] = pushbutton1_Callback(h0object, A)
% here I put the pushbuttons together in an array
L=[h1, h2, h3, h4, h5];
for i = 1:size(A,1)
if i == 0
set(L{i},'Backgroundcolor','w');
elseif i == 1
set(L{i},'Backgroundcolor','b');
elseif i == 2
set(L{1},'Backgroundcolor','g');
elseif i == 2
set(L{i},'Backgroundcolor','y');
end
end
end
end
Unfortunately I get:
Error using create_maze/pushbutton1_Callback (line 164)
Not enough input arguments.
Could anybody help me with this loop?
Thank you!
You need to think about the scope of functions
Any variables defined within a function that aren't output by it will be cleaned up (deleted) when the function finishes executing.
In the case of graphics objects a link to the push button handles will still actually exist somewhere as a child of the main figure window, but it will be mush easier if you output the handles somehow from 'create_maze'
it is safer to define the line
L=[h1, h2, h3, h4, h5];
at the end of create_maze, rather than trying to be tricky with nested functions which will give you limited advantage here, and possibly slight overhead.
Check out the mathworks website for more info on the scope of variables in nested functions, but to be on the safe side, be sure that all of functions could run without relying on the other having defined variables.
Ie. make sure functions only need their input variables
I come across a strange scaling in y- axis in a IEEE journal paper.
From top to bottom
y_axis = [0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001].
The scaling is not logaritmic. The space between the ticks are not equal. Definitely, it is not linear. You can see the big numbers (0.9... 0.999) and very small numbers(0.0001... 0.1) in detail in only one y-axis. I don't know how to do in MATLAB. I googled it, but i could not find. Can anyone help me? Thanks in advance.
The figure is the following code:
clear all
close all
set(0,'defaulttextinterpreter','latex')
P_tb = 1e-2;
Ntrial = 1e7; % # of Monte Carlo trials
jey=sqrt(-1);
omega_db = -15; % sidelobe gain of main antenna
omega = db2pow(omega_db); % omega in linear scale
F_db = [-5 -2 0 2 5];
JNR_db = -5:20;
beta_db = 2;
F_lin = 10.^(0.1*F_db);
JNR = 10.^(0.1*JNR_db);
beta = 10.^(0.1*beta_db);
temp = cell (length(F_db),1);
P_b = zeros (length(JNR_db), length(F_db));
for ii = 1:length(F_db)
SNR = JNR;
x = sqrt(omega);
F = F_lin(ii);
P_b(:,ii) = 1 - 1./(F+1).*(1-marcumq(x.*sqrt(2.*SNR./(F+1)),sqrt(2.*SNR.*F./(F+1))))-F./(F+1).*marcumq(sqrt(2.*SNR.*F./(F+1)), x.*sqrt(2.*SNR./(F+1)));
temp (ii) = {['$F=$' num2str(F_db(ii)) ' dB']};
end
figure,
h = plot(JNR_db, (P_b));
set(gca,'YTick',fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001]))
set(gca,'YTickLabel',num2cell(fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001])));
grid on
In the figure posted by the OP, the tickmarks are not at all equally distributed. Also, the scale of the axis is rather the inverse of sigmoidal (see below). To really see what the authors of that paper did, we can skeletonize the figure
im = conv2(im, fspecial('gaussian', [5, 5], 2));
im = ~bwmorph(im < 2.5, 'skel', inf);
and obtain the exact positions y_px as in
y_px = flipud(find(im(:, 285) == 0));
y_px([1, 2, 3, 11, 15, 19, 28]) = [];
I am removing some of the detections which are from the trendlines or from the -10 tick mark label of the x-axis.
If you plot the y-tick labels y_val (flipping your y_axis into ascending order) as a function of those pixel positions y_px, you can confirm that the relationship is exactly sigmoidal as suggested by #chapjc. However, in order to produce similar plots, you may rather want to invert the formula and define a function
px_y = #(y) log(-y ./ (y - 1));
You can use this function then for plotting. The paper you refer to shows data in a range x = -10 : 0.1 : 4. Let's plot in this same range a sine function somewhere between 0.0001 and 0.9999. Note that we use our scaling function px_y, and then replace the y-tick positions and labels
plot(x, px_y(0.7 + sin(x) / 4));
set(gca(), 'ytick', px_y(y_val), 'yticklabel', num2cell(y_val));
resulting in something that should look like this
In summary, you can define a function y_px to transform your y-data, and then set the ytick and yticklabel properties of your axes. Whatever scale you choose for this approach, it is important to transform both the ytick values and all y-data with the same function.
Try this:
set(gca,'YTick',fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001]));
set(gca,'YTickLabel',num2cell(fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001])));
Matlab wants the numbers to be in increasing order, so instead of reordering your numbers, I just invoked fliplr instead.
To get an idea of this custom y-axis space, you can do plot(linspace(-5,5,numel(y_axis)),fliplr(y_axis),'r'). This looked a lot like a dose curve, so plot an equation I found with hold on; x=-5:0.01:5; plot(x,exp(x)./(1+exp(x))). Here's what it looks like:
The form looks right. There is probably a constant on one of the terms to tweak the shape. If you want to put your data in this space, apply this function (yscFun = #(x) exp(x)./(1+exp(x)) or yscFun = #(x) 1./(1+exp(-x))). Then set the tick labels to y_axis with set(gca,'YTickLabel',num2cell(fliplr(y_axis))); as suggested by nispio.
This is the final solution that I found. Thank you very much. I did not know the sigmoid function. Below are the MATLAB codes for this puporse.
close all
clear all
%your desired y_ticks
y_axis = [0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001];
%order in increasing way
y_val = fliplr (y_axis);
% the Sigmoid function and its inverse
py_x = #(x) 0.5*erf(x*sqrt(pi/8)) + 0.5;
px_y = #(x) sqrt (8/pi)*erfinv (2*x - 1);
beta = 10^(0.1*-15);
F = 10^(0.1*-5);
JNR_db = -5:20;
SNR = 10.^(0.1.*JNR_db);
% my original data
P_b = # (x) 1 - 1./(F+1).*(1-marcumq(x.*sqrt(2.*SNR./(F+1)),sqrt(2.*SNR.*F./(F+1))))-F./(F+1).*marcumq(sqrt(2.*SNR.*F./(F+1)), x.*sqrt(2.*SNR./(F+1)));
P_b1 = P_b(sqrt(beta));
% tranfrom it using inverse function
P_b2 = px_y(P_b1);
figure,
plot(JNR_db, P_b2);
grid on
ylim ([ px_y(0.0001) px_y(0.9999) ]);
% tranform the desired y_tick using inverse function
set(gca(), 'ytick', px_y (y_val));
set (gca (), 'yticklabel', num2cell(y_val));
% % Sigmoid function verification
x_temp = linspace(-5,5,numel(y_axis));
figure
plot(x_temp, fliplr(y_axis), 'r');
hold on
plot (x_temp, py_x (x_temp), 'b' )
I am trying to figure out how to run the camera and stop the camera at the push of a button. If I cant do that, how do I set up camera to run within this figure and I will have it run all the time. Also I need to capture an image.
function faceCam2()
vid = videoinput('winvideo');
% Create a figure window
hFig = figure('Toolbar','none',...
'Menubar', 'none',...
'NumberTitle','Off',...
'Name','FaceScan');
%start camera
uicontrol( 'String', 'Start Preview',...
'Callback', 'preview(vid)',...
'Units','normalized',...
'Position',[0 0 0.15 .07]);
%stop
uicontrol( 'String', 'Stop Preview',...
'Callback', 'stoppreview(vid)',...
'Units','normalized',...
'Position',[.17 0 .15 .07]);
%snapshot
uicontrol( 'String', 'Pic',...
'Callback', 'data = getsnapshot(vid)',...
'Units','normalized',...
'Position',[0.34 0 .15 .07]);
%close window
uicontrol( 'String', 'Close',...
'Callback', 'close(gcf)',...
'Units','normalized',...
'Position',[0.51 0 .15 .07]);
end
I get the Error in matlab command window when I press a button. Quit works, but not the other 3. What do I need to do?
Thanks!
Undefined function or variable 'vid'.
Error while evaluating uicontrol Callback
The problem is that vid is a local variable in the function faceCam2 and is not visible to the callback. Here are a few methods to pass data to callback functions. When using nested methods, the code looks like this:
function faceCam2()
vid = videoinput('winvideo');
% Create a figure window
hFig = figure('Toolbar','none',...
'Menubar', 'none',...
'NumberTitle','Off',...
'Name','FaceScan');
%start camera
uicontrol( 'String', 'Start Preview',...
'Callback', #prevCallback,...
'Units','normalized',...
'Position',[0 0 0.15 .07]);
function prevCallback(hObject,eventdata)
preview(vid);
end
%...
end