How to pass the variables to data cursor's updatefcn (datacursormode) in MATLAB GUIDE.

Hi All,
I create a data cursor function (daracursormode) in the OpeningFcn().And I want to pass the variables got from "OpeningFcn()" into the "updatefcn()".But the result shows nothing in axes3.It seems like handles.y_fft does not pass into "updatefcn()".Here is the code...
I write an simplified case which can explan my question clearly.(I know the best way in this case is to put handles.y_fft outside "updatefcn" .)
Here is the guide looks like
Am I missing something or making mistake in using it?
Thank you so much!
Chloe

 Accepted Answer

Chloe - note the following three lines of code
dcm_obj = datacursormode(fig);
datacursormode on
set(dcm_obj,'UpdateFcn',@myupdatefcn);
The first line returns the data cursor mode object for the fig figure (so that which shows the sine wave); the second line then enables the data cursor mode for the current figure which is the GUI; and the third line assigns the update function to the figure...which will never fire because the data cursor mode is enabled for the GUI and not the object that dcm_obj refers to.
Also, just prior to updating the handles structure, do the FFT
handles.y_fft = abs(fft(handles.y));
guidata(hObject,handles);
If, like in your attached screen shot, you want the data cursor mode enabled for the GUI, then you could do something like
handles.dcm_obj = datacursormode(hObject);
set(handles.dcm_obj,'Enable','on','UpdateFcn',{@myupdatefcn,hObject});
Note that we will save the dcm_obj as a field to the handles structure. In the second line of code, we enable the data cursor mode for that object, and set its update function. We wrap the update function in braces so that we can pass an additional parameter, hObject, which is the handle to the GUI.
In order to account for the additional parameter, your update function will now look something like
function txt = myupdatefcn(~,event_obj,hFigure)
txt = '';
The problem with enabling the data cursor mode for the figure, is that you have two axes (names axes1 and axes3). This means that this mode will be enabled for both axes, and so the code will have to handle both cases as
% get the axes where the user has clicked
hAxesParent = get(get(event_obj,'Target'),'Parent');
% get the handles structure for the figure/GUI
handles = guidata(hFigure);
% which axes are we in?
if hAxesParent==handles.axes1
pos = get(event_obj,'Position');
txt = {['Time: ',num2str(pos(1))],...
['Amplitude: ',num2str(pos(2))]};
plot(handles.axes3,handles.y_fft);
elseif hAxesParent==handles.axes3
txt = 'what should go here?';
else
% do nothing
end
The above code should update the the other axes. The catch is that the data cursor mode is enabled for your axes3 as well.

13 Comments

Thank you for your reply! It is really helpful to clearify some important concepts!!
But I am still confused.The reason I count fft in "updatefcn" is that I want to test whether the handles structure could pass in "updatefcn" and do some signal processing.
In my real GUI,I will process a 3-D matrix(this is a video),show the 1st frame in axes1,implement "datacursormode" on axes1 to get cursor's position,then do the fft of the position(X,Y) in Z-direction and plot the fft curve in axes3.
Here is the question. The 3-D matrix has been pre-processed and already stored in handles structure (like handles.y in this case).But I cannot passed it in "updatefcn".
Again,Thanks for your answer.
Chloe - the handles structure can still be accessed in the updatefcn using the code
handles = guidata(hFigure);
as shown above. And yes, you can do some signal processing work there as well. I mocked up a simple GUI, similar to yours, and was able to do the above. (See attached.)
You don't want to "pass" handles as input to the updatefcn, but "retrieve" it with guidata.
Thank you so much for your considerate answer and correction. I will try your suggestion on my gui!! It is really helpful!!
Geoff, I try it in my real gui. But there is another question appeared.This problem happened before.here is the part of that code
With this code,the position cannot be shown on the figure.The error is "Error in custom datatip string function". Then I change my code as following,
Then the position(X,Y) is successfully shown on the figure in axes1.
Yesterday we talked about that example code and it works perfect.But when I try on my real gui, the position isn't showed again.The error is as same as the previous one.The code is as follows;
I must make some mistake but since it is the first time I design a GUI,it is a little hard to figure out what problem is. In my view, all variables have already saved in handles structure.I think it should show the result as similar as we got from yesterday.
I am sorry for the complication. Thanks again for all your patience.I am most appretiative of your help.
Chloe - can you attach the code instead? Just use the paperclip button to attach your m file and fig file. It will be easier to understand what is going wrong, rather than looking at screen shots. Just remember that once you choose the file, you have to then press the Attach File button to ensure that the file gets uploaded to your comment.
You have to set the text string, txt, with some text (not just an empty string) for all cases. I see the if hAxesParent==handles.axes3 in the above code, so there will have to be an else block to initialize txt with something. That is why in my example I had set
txt = 'what should go here?';
and should have done the same for the else block.
Sure. Since the original code need some confidential data,I will write a similar case for this and upload it. Thank you!
okay. Looking more closely at the updatefcn, the code to build the txt output variable seems to be
txt = stract('x:',...);
I think that you mean strcat instead. This could be the source of the error. I was able to reproduce the problem in my environment. I had thought maybe an error would be written to the Command Window indicating invalid function, but nope. So try replacing the above with
txt = strcat('x:',);
Note: there is a try catch statement surrounding the updatefcn call, so that is why nothing is written to the command window. The error, because of the invalid function name, is thrown and caught, and the Error in custom datatip string function is displayed in the tool tip box.
Sorry for the late reply. I correct strcat instead.But the error is still there.Here is the similar case attached. Thank you Geoff.
Chloe - try putting a breakpoint in the myupdatefcn and then re-run the code. When you select a point in your image, the debugger will pause at the line with the breakpoint and you can step through the code. You would see the problem is with the following two lines
handles.FrameMatrix_fft = abs(fft(handles.FrameMatrix(...
handles.x,handles.y,:)));
plot(handles.axes3,handles.FrameMatrix_fft);
Your FrameMatrix is a 256x320x800, so the
handles.FrameMatrix(handles.x,handles.y,:)
returns a 1x1x800 matrix which you do the FFT on, which produces a matrix with the same dimension. When the code tries to plot this, the error
Error using plot
Data may not have more than 2 dimensions
is raised. Try removing the singleton dimensions using squeeze as
data = squeeze(handles.FrameMatrix(handles.x,handles.y,:));
handles.FrameMatrix_fft = abs(fft(data));
plot(handles.axes3,handles.FrameMatrix_fft);
That should allow the data to be plotted correctly.
-------------
Note though the following lines of code
pos = get(event_obj,'Position')
handles.x = round(pos(1));
handles.y = round(pos(2));
txt = strcat('x:',num2str(handles.x(1,1)),'y:',num2str(handles.y(1,1)));
data = squeeze(handles.FrameMatrix(handles.x,handles.y,:));
x and y are the position coordinates of the cursor object - this is fine. But your image is 3D with the first dimension being the number of rows, the second is the number of columns, and the third is something else. Since x is along the x-axis, this actually corresponds to the columns of the matrix. y is along the y-axis, so this correspons to the rows of the matrix. So you will need to replace the
data = squeeze(handles.FrameMatrix(handles.x,handles.y,:));
with
data = squeeze(handles.FrameMatrix(handles.y,handles.x,:));
Try making the above changes and see what happens!
Hello Geoff,
Sorry for replying late. I have tried but it seems the problem is still there. Then I put the breakpoints at
data = squeeze(handles.FrameMatrix(hanles.y,handles.x,:));
And the coordinate shows
Then I set the breakpoint at
plot(handles.axes3,handles.FrameMatrix_fft);
And the coordinate shows
It seems like the problem happen at fft step
pos = get(event_obj,'Position');
handles.x = round(pos(1));
handles.y = round(pos(2));
txt = {['x:',num2str(handles.x(1,1))],['y:',num2str(handles.y(1,1))]};
data = squeeze(handles.FrameMatrix(hanles.y,handles.x,:));
handles.FrameMatrix_fft = abs(fft(data));
plot(handles.axes3,handles.FrameMatrix_fft)
I also try to comment "handles.FrameMatrix_fft = abs(fft(data));" and just plot the "data", but the problem is still showed in there.
if hAxesParent==handles.axes1 % show the cursor's position and get its FFT
pos = get(event_obj,'Position');
handles.x = round(pos(1));
handles.y = round(pos(2));
txt = {['x:',num2str(handles.x(1,1))],['y:',num2str(handles.y(1,1))]};
handles.data = squeeze(handles.FrameMatrix(hanles.y,handles.x,:));
% handles.FrameMatrix_fft = abs(fft(data));
plot(handles.axes3,handles.data);
elseif hAxesParent==handles.axes3 % check the Amplitudes
pos = get(event_obj,'Position');
txt = {['Time: ',num2str(pos(1))],...
['Amplitude: ',num2str(pos(2))]};
else
% do nothing
end
I really appreciate your help.
Thanks so much. Chloe
Chloe - there is a typo in the line
handles.data = squeeze(handles.FrameMatrix(hanles.y,handles.x,:));
of myupdatefcn. Note the hanles.y instead of handles.y. Update the above line and try again.
Dear Geoff,
I really appreciate your help.With your help,I learn lots of GUI in MATLAB. Finally, I have finished my GUI design.It is really fun to play with GUI.And I think I will develop the advanced version of that GUI.
Thank you Geoff!
Best regards,
Chloe

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!