How do I use linkdata to link a plot to variables that are updated with a callbackfunction?

7 views (last 30 days)
I have an image on which I create an ROI using drawrectangle. I use the position property of the roi to do some processing and then plot something. I want my plot to update itself (without creating a new figure) everytime I resize the ROI interactively (i.e. drag it with the mouse).
I'm using an addlistener to detect the event (ROIMoved), and call a callbackfunction, and the way I can pass variables to and from the callbackfunction is using the UserData field of the source. But when that is updated, my plot doesn't update.
Edit: I also tried including the XDataSource and YDataSource in my plot function according to this post and yet it still doesn't update my plot.
Edit 2: I have realized that the problem is that I need to call roi.UserData.vector_I'm_plotting, for the linkdata to detect the change. When I type that in the command line after I have moved the ROI, it updates the plot. The problem is I can't call this in my callbackfunction. I have to call src.UserData.vector_I'm_plotting, and that doesn't seem to do the trick.
If you could tell me if I am doing something wrong and how to fix it, I would appreciate it a lot.
I have attached the data I am using from workspace and here is my code:
delay= Delay_mm;
%% Make the 2D color map and draw roi
figure
pcolor(delay,Wavelength,Intensity_mean');
shading('interp');
xlabel('time delay (mm)');
ylabel('wavelength (nm)');
title(Title,'Interpreter', 'none');
roi = drawrectangle;
%% process roi data
position = roi.Position;
lambda_st_idx = find(abs(Wavelength - position(2)) == min(abs(Wavelength-position(2))));
lambda_end_idx = find(abs(Wavelength - (position(2)+position(4))) == min(abs(Wavelength-(position(2)+position(4)))));
delay_st_idx = find(abs(delay - position(1)) == min(abs(delay-position(1))));
delay_end_idx = find(abs(delay - (position(1)+position(3))) == min(abs(delay-(position(1)+position(3)))));
Int_cut = Intensity_mean(delay_st_idx:delay_end_idx,lambda_st_idx:lambda_end_idx);
delay_cut = delay(delay_st_idx:delay_end_idx);
Int_cut_mean = mean(Int_cut, 2);
%% create data structure to put in UserData and linkdata to plot
allthedata.delay = delay;
allthedata.wavelength = Wavelength;
allthedata.Intensity = Intensity_mean;
allthedata.delay_cut = delay_cut;
allthedata.Int_cut = Int_cut_mean;
roi.UserData = allthedata;
figure
plot(roi.UserData.delay_cut, roi.UserData.Int_cut,'XDataSource','roi.UserData.delay_cut','YDataSource','roi.UserData.Int_cut', LineWidth=1);
xlabel('time delay (t0)');
linkdata on
%% update plot when roi changes
% addlistener(roi,'MovingROI',@roiposition);
addlistener(roi,'ROIMoved',@roiposition);
function roiposition(src,evt)
evname = evt.EventName;
Wavelength = src.UserData.wavelength;
Intensity_mean = src.UserData.Intensity;
delay = src.UserData.delay;
switch(evname)
case{'MovingROI'}
% same stuff as below
case{'ROIMoved'}
position = evt.CurrentPosition;
lambda_st_idx = find(abs(Wavelength - position(2)) == min(abs(Wavelength-position(2))));
lambda_end_idx = find(abs(Wavelength - (position(2)+position(4))) == min(abs(Wavelength-(position(2)+position(4)))));
delay_st_idx = find(abs(delay - position(1)) == min(abs(delay-position(1))));
delay_end_idx = find(abs(delay - (position(1)+position(3))) == min(abs(delay-(position(1)+position(3)))));
Int_cut = Intensity_mean(delay_st_idx:delay_end_idx,lambda_st_idx:lambda_end_idx);
delay_cut = delay(delay_st_idx:delay_end_idx);
Int_cut_mean = mean(Int_cut, 2);
src.UserData.delay_cut = delay_cut;
src.UserData.Int_cut = Int_cut_mean;
end
end
  1 Comment
pistachionut
pistachionut on 1 May 2022
I have declared "roi" a global variable and my code works for now but I feel wary of using global variables. If anyone knows a better way, please let me know.

Sign in to comment.

Answers (1)

SAI SRUJAN
SAI SRUJAN on 23 Jan 2024
Hi,
I understand that you are facing an issue with the plot not updating when you adjust the ROI, we can use the 'refreshdata' function in MATLAB.
The 'refreshdata' function in MATLAB is used to refresh the data in a plot when the underlying data sources have been changed. It works by updating the plot with the current values from the variables or expressions specified as the 'XDataSource' and 'YDataSource' properties of the plot.
Please refer to the provided example to understand the working of'refreshdata',
S.a = 1:20;
S.b = S.a.^2;
px = axes;
hold on;
ln = plot(S.a,S.b);
ln.XDataSource = 'S.a';
ln.YDataSource = 'S.b';
S.b = S.a*2;
refreshdata(ln);
For a comprehensive understanding of the 'refreshdata' function in MATLAB, please refer to the following documentation.
I hope this helps!

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!