Plotting graph in the appdesigner from the object handle - h

Hi,
I have code below that plots the graph via object handle 'h'. I would like to embed this plot into appdesigner and I am having problem with doing that. Normally I would plot in the appdesigner with plot(app.UIAxes,x,y). How could I do it if I only have handle 'h' ?
RFCF1 = 2400e6; % 2.4 GHz
RFBW1 = 200e6; % 200 MHz
IFBW1 = 20e6; % 20 MHz
IMT1 = [99 0 21 17 26;
11 0 29 29 63;
60 48 70 86 41;
90 89 74 68 87;
99 99 95 99 99];
writecell(num2cell(IMT1), 'imt1.txt')
h = OpenIF('IFLocation', 'MixerOutput')
h.SpurFloor = 85;
addMixer(h,IMT1, RFCF1, RFBW1, 'low', IFBW1);
report(h);
figure(1);
show(h)
h.Mixers(1).MixingType = 'high';
report(h)
figure(2);
show(h);
Thank you,

 Accepted Answer

The show() function within the OpenIf classdef creates its own indpendent figure and axes. The only way to show the plot within your app is to copy if after it's created.
Steps to move the plot into App Designer
1) Create the Intermediate Frequency ("IF") object (h) but do not plot it yet.
% Based on the code from your question (simplified)
RFCF1 = 2400e6; % 2.4 GHz
RFBW1 = 200e6; % 200 MHz
IFBW1 = 20e6; % 20 MHz
IMT1 = [99 0 21 17 26;
11 0 29 29 63;
60 48 70 86 41;
90 89 74 68 87;
99 99 95 99 99];
h = OpenIF('IFLocation', 'MixerOutput')
h.SpurFloor = 85;
addMixer(h,IMT1, RFCF1, RFBW1, 'low', IFBW1);
2) Create an invisible figure.
fig = figure('visible','off');
3) While the invisible figure is the current figure, create the IF planning plot.
show(h) % where h is your IF object handle.
4) Use copyobj() to copy the content of the IF axes to your app axes.
% Create UIFigure and UIAxes for demo-only!
app.UIFigure = uifigure();
app.UIAxes = uiaxes(app.UIFigure);
% Copy to App axes; store the new object handles.
IFAxes = gca(fig);
newPatchObjects = copyobj(IFAxes.Children, app.UIAxes); % the 2nd input is the handle to your app axes.
5) Add the legend. Here we detect which patch objects have a non-empty DisplayName property to determine what goes in the legend.
hasDisplayName = ~cellfun(@isempty,{IFAxes.Children.DisplayName});
legend(app.UIAxes, newPatchObjects(hasDisplayName));
6) If you want to regain the interactive text summaries that appear when you click on a patch object within the original figure, copy the ButtonDownFcn values to the new patch objects. See notes below for background info.
% Set the app's figure handle visibility
app.UIFigure.HandleVisibility = 'on'; % or 'callback'
set(newPatchObjects, {'ButtonDownFcn'}, get(IFAxes.Children,'ButtonDownFcn'))
7) Delete the original, invisible figure
delete(fig)
Now you can click on the patch objects in your App and wear your hero cape proudly.
What controls the text that appears when clicking on a patch?
This section is just for the curious folks.
When you click on a patch object (the colored rectangles) in an Intermediate Frequency Planner plot, it invokes a ButtonDownFcn defined in OpenIF.m > show() > @patchbuttondown.
The patchbuttondown function creates a cell array of text stored in UserData.htext of the patch object. The htext values are empty until you click on the object and when the text box is deleted from the plot, the htext values become empty again. That's why the text values do not copy unless they happen to be active when copied.
After copying the @patchbuttondown handle to the ButtonDownFcn properties of the copied patch objects, clicking on those objects within App Designer will invoke the function defined in OPenIF.m.

6 Comments

Hi Adam,
Thank you on th epromot reply. I have probably misuderstood somehing. Below is the current code:
ax=show(h);
fig=figure('visible','off');
show(h);
copyobj(app.UIAxes,ax)
IFAxes=gca();
copyobj(IFAxes.Childreb,app.UIAxes)
delete(fig)
Thank you
Hi Adam,
Got it. Thank you very much. This method creates figure that is more like an image in comparison withthe original becasue legend, pop-ups etc.. are disabled. Is there any other way that original figure could be emeded into application window?
Thakn you!
I didn't realize show() returns the figure handle. This version below is slighly better.
figure('visible','off');
fig = show(h);
IFAxes = gca(fig);
copyobj(IFAxes.Children, app.UIAxes)
To include the legend you have 2 options.
1) recreate the legend using
legend(app.UIAxes, ___) % fill in the missing inputs
or 2) instead of copying the axis children, copy the figure children, but then you'll need to reposition of the copied axis within your figure.
h = copyobj(fig.Children, app.UIFigure); % the 2nd input should be your app figure handle
copiedAxes = findobj(h,'Type','Axes');
set(copiedAxes,'Units',app.UIAxes.Units,'Position',app.UIAxes.Position)
S.R.'s answer moved here as a comment.
Thank you Adam, but it looks like there is no way that this original figure can be shown in the appdesigner. Code works in a sense that I can see bars that I need to see but after clicking on the bars I cannot get critical information which would be spurs information.
I noticed that if I use save figure , savefig(show(h),'Spurs'); , figure get saved with all of the information but I do not see how to import it into appdesigner or UIAxes. Maybe this method would work better if it is possible to somehow load figure into application?
Thank you!
I've updated my answer to show how to make the App Designer plot exhibit the same behavior as the original plot. It also shows how to recreate the legend.
Hi Adam,
This code modifies pop-up figure not the the "UIAxes"?
Thank you,

Sign in to comment.

More Answers (1)

Thank you Adam, but it looks like there is no way that this original figure can be shown in the appdesigner. Code works in a sense that I can see bars that I need to see but after clicking on the bars I cannot get critical information which would be spurs information.
I noticed that if I use save figure , savefig(show(h),'Spurs'); , figure get saved with all of the information but I do not see how to import it into appdesigner or UIAxes. Maybe this method would work better if it is possible to somehow load figure into application?
Thank you!

6 Comments

See the first comment within the code under step 4.
Hi Adam,
I have seen that and commented out those two lines. The entire code for plotting is below. This code errors out?
fig = figure('visible','off');
show(h)
% Copy to App axes; store the new object handles.
IFAxes = gca(fig);
newPatchObjects = copyobj(IFAxes.Children, app.UIAxes); % the 2nd input is the handle to your app axes.
hasDisplayName = ~cellfun(@isempty,{IFAxes.Children.DisplayName});
legend(app.UIAxes, newPatchObjects(hasDisplayName));
% Set the app's figure handle visibility
app.UIFigure.HandleVisibility = 'on'; % Replace fig handle with your handle
set(newPatchObjects, {'ButtonDownFcn'}, get(IFAxes.Children,'ButtonDownFcn'))
delete(fig)
Error using uiaxes (line 47)
'Parent' cannot be set to a deleted object.
Thank you,
Which line is line 47? I don't think that error is from any of the lines in the code you shared above. If that line is generated from the code in my answer, please provide the entire error message and share the line of code producing the error.
Also, have you tried running only the code from my answer?
Hi Adam,
Problem is solved now. I get the plot. Thank you!
Is there a way to embed plot for plotting mixer spurs? I do not see how to add and plot this plot in the appdesinger either.
This is what Matlab help file suggests in the example for plotting mixer spurs:
plot(Mixer,'MIXERSPUR',1,Pin,RF_frequency);
Thank you
Hi Adam,
It looks like that code works very well for plotting mixer spurs as well.
Thank you!
Sounds good! Glad I could help out.

Sign in to comment.

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Products

Asked:

on 14 Jul 2020

Edited:

on 4 Oct 2020

Community Treasure Hunt

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

Start Hunting!