Using an axes handle as an input for a function

18 views (last 30 days)
Hi everyone,
I'm working on a MATLAB app which does some plotting, and to simplify the code, I was trrying to generalise my plotting function so that I can tell it whether to plot everything on axes A or on axes B.
Essentially I have a preview window where you can add options to the plot which is then shown in "app.smallpax", but then I switch to a saving window where I want the exact same plot, with all the options you selected in the preview, but just larger and with a save button.
Therefore, I want to plot the same thing in 2 different places, but maintain also options for grids, axes, colorbars etc which don't come packaged in the graphics object porperties. I have looked into copyobj but it does not transfer colorbars and grid settings, which leads to a lot of duplicate code and logic to reapply them there again, due to how the option buttons and tickboxes are coded.
This below is the function I'm trying to generalise. I added a "target" handle which would point to either a small polar axes "app.smallpax" (for the preview window) and a big one, "app.bigpax" (for the saving window).
function PlotPolarCoordinates(app, target)
delete(target) % remove any previous graph
if strcmp(target,'app.smallpax') ==1 % check what the target is and assign it to the corresponding UI panel
app.smallpax = polaraxes(app.SmallFingerprintPlotPanel);
elseif strcmp(target,'app.bigpax') ==1 % check what the target is and assign it to the corresponding UI panel
app.bigpax = polaraxes(app.BigFingerprintPlotPanel);
end
% plot the polar scatter graph on the target axes
app.fingerprint_plot = polarscatter(target,app.theta - app.angle*pi/180,app.rho,1,app.data_processed(:,app.AxisPlottingDropDown.Value),'.');
% set the target axes and any grid on top of the plot
set(target,'Layer','top','LineWidth',1,'FontWeight','bold','GridAlpha',1,'MinorGridAlpha',1,'RColor',[0.41176 0.41176 0.41176],'ThetaColor',[0.41176 0.41176 0.41176])
colormap(target,app.ColorMapDropDown.Value);
clim(target,[app.cmin,app.cmax]);
end
I assumed I could just place it within the set , clim or colomp commands just as a variable given that I am passing it as a string (i.e.
app.PlotPolarCoordinates('app.smallpax')
%or
app.app.PlotPolarCoordinates('app.bigpax')
This is essentially a consequence of a lot of smaller issues and I have a feeling that I'm wrapping myself up in a spaghetti code.
Any help on the best way of doing this would be greatly welcome.
Thanks!
  2 Comments
dpb
dpb on 16 May 2022
In
delete(target) % remove any previous grap
...
app.fingerprint_plot = polarscatter(target,app.theta - app.angle*pi/180,app.rho,1,app.data_processed(:,app.AxisPlottingDropDown.Value),'.');
target must be the actual handle of the target axes -- not a string variable.
But, if you delete target, then it is no longer there to plot into later on; you've got to create a new one -- in which your subsequent reference is NULL and BOOM!
Would need more detail in the actual UI, but something at least closer would be something similar to
function PlotPolarCoordinates(app, target)
delete(app.pax) % remove any previous graph
if strcmp(target,'small')
app.pax=polaraxes(app.SmallFingerprintPlotPanel);
else
app.pax=polaraxes(app.BigFingerprintPlotPanel);
end
% plot the polar scatter graph on the target axes
app.fingerprint_plot=polarscatter(app.pax,app.theta - app.angle*pi/180,app.rho,1,app.data_processed(:,app.AxisPlottingDropDown.Value),'.');
% set the target axes and any grid on top of the plot
set(app.pax,'Layer','top','LineWidth',1,'FontWeight','bold','GridAlpha',1,'MinorGridAlpha',1,'RColor',[0.41176 0.41176 0.41176],'ThetaColor',[0.41176 0.41176 0.41176])
colormap(app.pax,app.ColorMapDropDown.Value);
clim(app.pax,[app.cmin,app.cmax]);
end
The delete still may not work as intended; that will depend greatly on just how the UI is constructed, as is, it should be the last one that was created here; that may not be the one really want...what this does is create a small or large one depending on the input; it isn't clear that the last one that was plotted is always the one that should be delete first...
Dennis Premoli
Dennis Premoli on 16 May 2022
This is essentially the UI:
Preview/options window
Saving window
This whole debacle really is due to copyObj not doing some very useful things, although I am aware that working in a more modular fashion is always best.
That said, I think I realised my mistake, in that I forgot how my own code worked. I was running under the assumption that app.smallpax was somehow a MATLAB object/handle, while it is in fact a varaible I created (stupid me).
I also find myself constantly butting against the inability to add extra handles to callback functions ceated by MATLAB. So I can have a AxisCheckBoxValueChanged(app, event) but I cannot call it as AxisCheckBoxValueChanged(app, event, target), to use it as a helper function in itself.
Therefore, I find myself constantly creating helper functions that I then call in 1 line under each callback, as seen here below. I wish, for example, that I could call AngleEditFieldValueChanged and also pass it a target axes, but it appears I can only do that with a global varibale or hard coding it in.
% Callback function
function AngleEditFieldValueChanged(app, event)
app.angle = abs(app.AngleEditField.Value);
app.Knob.Value = app.angle;
app.PlotPolarCoordinates('app.smallpax')
end
% Value changed function: AngleSpinnerEditField
function AngleSpinnerEditFieldValueChanged(app, event)
app.angle = abs(app.AngleSpinnerEditField.Value);
app.Knob.Value = app.angle;
app.PlotPolarCoordinates('app.smallpax')
end
% Value changing function: Knob
function KnobValueChanging(app, event)
end
app.angle = event.Value;
app.AngleSpinnerEditField.Value = app.angle;
app.PlotPolarCoordinates('app.smallpax')
In my defense, this code has been written by me and another person so the whole pax debacle was not my creation ahah but I am trying to coincide my limited knowldge of MATLAB with what I know are generally good coding practices.

Sign in to comment.

Answers (1)

aditi bagora
aditi bagora on 17 Jan 2024
Hello Dennis,
I understand that you are trying to write a modular code where you can pass objects in the callback functions.
We can use “UserData” property that is associated with the UI components. You can store your data in the form of a structure and access it in the callback functions.
Below is the documentation link that contains details about how “UserData” property can be used to share data across callbacks.
Hope this helps!
Regards,
Aditi

Categories

Find more on Graphics Object Programming in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!