- In your UI, do I see is the uiaxes component, and you are trying to put inside it an imagesc output?
- As I see, your outer loop calculates the each step of your simulation. Within it, you should plot the electric field to the axis in the UI. You can do that if you add an optional argument, and that is handle for the uiaxis figure.
Passing real time plot data from a Matlab function to App Designer for plotting
101 views (last 30 days)
Show older comments
Hi,
Once again I find myself in a pickle that I'm hoping one of you guys may be able to help resolve.
I am using App Designer for the first time to contruct an app. From this app, I wish to call a function, bring the plot data into my app, and show the electromagnetic wave propagating in real time - just like it does in the figure when I run the Matlab function. Is this possible? At present, once I click on the 'Ping' button (see image below), the program runs then after a short while the final result is plotted (not filling the full box - but that is another problem)!
Best regards,
Andy
The code is as follows:
In my App I have the following to call the function fdtd_time_reversal
[E,frames] = fdtd_time_reversal(X,Y,app.signal,app.media);
imagesc(app.UIAxes2,E)
axis image
colormap(app.UIAxes,"jet");
app.frames
In my matlab function, I have the following
function [E,frames] = fdtd_time_reversal(X,Y,signal,media
% Defined parameters etc. to set up the FDTD solver
Then
% Start the main loop for FDTD calculations
%*****************************************************
% The outer loop enters each step, one at a time, while the inner loop inputs that
% step for each trace.
for j = 1:Nt,
for i = 1:tr;
% enter the signal from the last time step to the first (reversed in time)
%The Electric field is initiated by creating a magnetic loop
hx((i-1)*space+nb+start,offset+nb) = signal(i,j);
hy((i-1)*space+nb+start,offset+nb) = -signal(i,j);
hx((i-1)*space+nb+start,offset+nb+1) = -signal(i,j);
hy((i-1)*space+nb+start+1,offset+nb) = signal(i,j);
ezy((i-1)*space+nb+start,offset+nb)=0;
ezx((i-1)*space+nb+start,offset+nb)=0;
end;
% Advance the fields using code 'fdtd_andy'
[ezx,ezy,hx,hy] = fdtd_andy(ezx,ezy,hx,hy,alphaex,alphaey,alphamx,alphamy,betaex,betaey,betamx,betamy);
%The extra layers from the boundary conditions are removed
E=(ezx+ezy);
[a,b] = size(E);
E = E(33:(a-32), 33:(b-32));
%The desired signal is recorded
% V(1:array,j)=[E(rstart:rspace:rstart+(array-1)*rspace,offset+depth)];
%The current electric field is plotted and saved for the movie
% figure(2)
colormap(jet)
imagesc(E)
caxis([-100 100])
axis image
frames(j)=getframe;
end;
%######################################################################
3 Comments
Accepted Answer
Benjamin Kraus
on 9 Feb 2024
There seems to be at least three difficulties you are running into:
- One is about calling the axis command without specifying an axes handle.
- One is a difference between regular Axes and UIAxes.
- One is a question about getting real time results plotted in App Designer.
Calling the axis command without specifying a handle
This line of code:
axis image
Will operate on the "Current Axes", but by default the axes that is within an App Designer app is never the current axes. Therefore, you always need to explicitly state which axes you want to operate on. This is a simple change:
axis(app.UIAxes, 'image')
This same statement applies to:
- The colormap command (which by default works on the current figure), but you can tell it to work on either a particular figure or a particular axes: colormap(app.UIAxes, jet).
- The caxis command
- The imagesc command
- etc.
Looking at your function called "fdtd_time_reversal", it doesn't provide any way to specify which axes to use when calling colormap or imagesc or axis or getframe. You will need to find a way to fix that issue if you want to use this code within App Designer.
Alternatively you can set the HandleVisibility of your App's Figure to 'on' so that it allow axes inside your App to be the current axes. This is by far the simplest solution, but it comes with some drawbacks. Namely, if you have your App open and someone calls plot at the MATLAB command line, it will mess with the graphics inside your App. For this reason, this is not recommended.
app.Figure.HandleVisibility = 'on';
Differences between regular Axes and UIAxes
Short summary: After calling imagesc, you want to call:
imagesc(app.UIAxes,E)
axis(app.UIAxes, 'image')
xlim(app.UIAxes, 'tight')
ylim(app.UIAxes, 'tight')
This will tighly crop your axes limits to just fit your image.
Details
When you call the imagesc command, the imagesc command does a few things:
- It creates an image object with the requested data.
- It switches the YDir on the axes to 'reverse' so your image is right-side-up.
- It sets the limits to be tightly cropped around your image.
Those second two bullets don't always happen, but rather they are conditional on the value of the NextPlot property on the axes or UIAxes.
- When NextPlot is set to 'replace' (this is the same as hold off) then the imagesc command will set the YDir and also the axes limits. This is the default behavior for regular Axes.
- When NextPlot is set to 'add' (this is the same as hold on) then the imagesc command will not set the YDir or the axes limits.
- When NextPlot is set to 'replacechildren', then the imagesc command will set the YDir to 'reverse', but it won't set the limits. This is the default behavior for UIAxes.
So, in your images, you can see the limits are not tightly cropped around your image ("not filling the full box - but that is another problem"). That is because the UIAxes you are using has NextPlot set to 'replacechildren', so the limits are not being updated.
Real time results plotted in App Designer
I didn't entirely follow the issue you were experiecing in this regard, but I'm going to speculate a little.
You said "once I click on the 'Ping' button (see image below), the program runs then after a short while the final result is plotted".
This is most likely because you are not giving the graphics system a chance to update while your code is running.
If you call multiple graphics commands in a row, without any breaks, then MATLAB will only draw the last picture.
Basically, in your for loop:
function [E,frames] = fdtd_time_reversal(ax, X, Y, signal, media) % Note I added "ax" here.
for j = 1:Nt
for i = 1:tr
% Do some math
colormap(ax, jet)
imagesc(ax, E)
caxis(ax, [-100 100])
axis(ax,'image')
xlim(ax, 'tight')
ylim(ax, 'tight')
drawnow % This command will tell MATLAB to draw this frame before moving on.
end
end
More Answers (0)
See Also
Categories
Find more on Log Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!