Plots in App Designer have very small y-axis

I am using UIAxes in app desiger to display images and graphs as specified by the user. The images work perfectly, using the answer here
https://www.mathworks.com/matlabcentral/answers/360670-imshow-in-app-designer-image-size-doesn-t-fit
However, I am having issues with the graphing aspect. It appears that MATLAB is scaling the figure y-axis based upon the differences in the y-data plotted.
Graphs1.JPG
In most cases, I can live with this since the data is still legible. However, changing what the x-axis represents (which is the whole point of graphing) can end up with some very bad results.
Graphs3.JPG
This is completely illegible. Furthermore, for an unknown reason, the last two graphs cut out my ytitle (the code is the same line for line, only variables change, and it works elsewhere.
Making the issue weirder, if I graph a single number (which I would assume would change the size of the yaxis to nothing from the above examples) ends up with a very nice looking graph...
Graphs4.JPG
Things I have tried:
Increasing the size of the plot in the same way as the images in the answer above
Scaling the data so that x-axis and y-axis will always be the same range (i.e. both will be from 0-80 even if the raw data is from 2-2.5 on the y-axis)
Trying to alter the answer here to work with appdesigner (it errors btw)
app.UIAxesS1.Units = 'normalized';
app.UIAxesS1.Position = [0 0 1 1];
Changing the dataAspectRatio and PlotBoxAspectRatio in the axes properties tab and setting them to manual (has no effect)
Graphs5.JPG
Using the set position function to change the position of the plot
h = plot(....)
set(h,'Position',[0 0 1 1]) This one says it cannot work on a line property
set(app.UIAxes,'Position',[0 0 1 1]) This one just changes the UIAxes to fill the entire figure and doesn't change the plotted data
I am sure there is a super stupid error that I am making with parent/children things, but I am not sure what is happening. If anyone would like the other code that manipulates it for the images I can post that, but this scaling issue happens even without displaying any images. Thank you to anyone who has made it this far
Code to graph the data (xAxis, yAxis are my data points). Note: The ylim and xlim is the way I got enough room for my data labels
plot(app.UIAxesS2, xAxis, yAxis(2,:), 'k*--'); % to plot the data in xAxis and yAxis variables
title(app.UIAxesS2, []); % Removing title, adding axis labels
xlabel(app.UIAxesS2, xlab);
ylabel(app.UIAxesS2, 'Kt Values');
xticks(app.UIAxesS2, xAxis); % Changing ticks and tick labels for xAxis
app.UIAxesS2.XAxis.TickLabels = xlabs;
text(app.UIAxesS2, xAxis - 0.1, yAxis(2,:) + 0.3, num2cell(round(yAxis(2,:),2))); %Adding data labels
app.UIAxesS2.YDir = 'normal'; %Flipping direction of the y axis
ylim(app.UIAxesS2, [min(yAxis(2,:)) - 0.5, max(yAxis(2,:)) + 0.5]); %Refining the limits of the axis
xlim(app.UIAxesS2, [min(xAxis) - 0.5, max(xAxis) + 0.5]);

8 Comments

Are you using axis(UIaxesS2,'tight')?
Hey Adam,
When I put that in (changing it to axis(app.UIAxesS2, 'tight') because app designer) it removes the y-axis label and doesn't change anything about the height of the axis (see the leftmost graph where I applied it). I was not using it previously
Graphs6.JPG
I wasn't recommending that you use "axis tight"; I was checking if that was the problem and would have recommended removing that.
When you first open the app, the axes appear correctly but after plotting, the y axis shrinks. Is that correct? Could you provide the full code to the function where this happens?
Oh sorry I misinterpreted. Yes when I start the app the axes are standard square axes, and then when I graph it goes strange. Here are the starting conditions
Here is the full code for the graphing section. The first 125ish lines are all to assemble the various conditions and data to graph, but the output is just a 4xM matrix (yAxis) and a 1xM vector (xAxis)
function graphingFunc(app, searchString, info)
% This function is designed to graph the values based upon the selected X-axis value
special = 0;
% This section will create the
switch '_'
case searchString(1) %This would be to graph IFS, XLS, Inlet
xAxis = [1:3];
xlab = '';
xReplace = [{'I'}, {'X'}, {'N'}];
xlabs = [{'IFS'}, {'XLS'}, {'Inlet'}];
repLoc = 1;
case searchString(2) %This would be to graph based on cutout (octagonal, rectangular)
% Need logic to create the search strings better than the other methods
% Same overall linear dimension, not same rectangular cutout area (ughhh)
special = 1;
% Going to make the cell array of strings here, then jam it into the following logic for
% the other times
% String 0 cutout
str1 = searchString;
str1(2) = 'R';
str1(8) = '0';
% String 2 cutout
str2 = searchString;
str2(2) = 'O';
a = num2str(str2num(str2(6)) - 2);
b = num2str(str2num(str2(7)) - 2);
str2(6) = a(1);
str2(7) = b(1);
str2(8) = '2';
% String 3 cutout
str3 = searchString;
str3(2) = 'O';
a = num2str(str2num(str3(6)) - 4);
b = num2str(str2num(str3(7)) - 4);
str3(6) = a(1);
str3(7) = b(1);
str3(8) = '3';
% String 4 cutout
str4 = searchString;
str4(2) = 'O';
a = num2str(str2num(str4(6)) - 6);
b = num2str(str2num(str4(7)) - 6);
str4(6) = a(1);
str4(7) = b(1);
str4(8) = '4';
app.Help_17.Visible = 'on';
xAxis = [0, 2, 3, 4];
xlab = 'Cutout Rows (# Holes)';
xlabs = {0, 2, 3, 4};
xReplace = xlabs;
specialStrings = {str1, str2, str3, str4};
case searchString(3) %This would be to graph %45°
% Same as rect octagonal cases, will make strings here
special = 1;
xlab = '%45°';
xAxis = 20:10:80;
xlabs = {};
specialStrings = {};
for i = xAxis
str = searchString;
str(3:4) = num2str(i);
xlabs = [xlabs {i}];
specialStrings = [specialStrings, {str}];
end
xReplace = xlabs;
case searchString(6) %This would be to graph rows
xAxis = [1:7];
xlab = 'Rows (# Holes)';
xReplace = [{'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}];
xlabs = xReplace;
repLoc = 6;
case searchString(7) %This would be to graph columns
xAxis = [1:7];
xlab = 'Columns (# Holes)';
xReplace = [{'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}];
xlabs = xReplace;
repLoc = 7;
case searchString(10) %This would be to graph based on plate size
xAxis = [3, 5, 6];
xlab = 'Plate Size (D)';
xReplace = [{'3'}, {'5'}, {'6'}];
xlabs = [{'3D'}, {'5D'}, {'6D'}];
repLoc = 10;
end
yAxis = zeros(4,length(xReplace));
for i = length(xReplace):-1:1
if special
newSearch = specialStrings{i};
else
newSearch = searchString;
newSearch(repLoc) = xReplace{i}; % Will replace the specific part of the search string
end
[kTvalues, ~, ~, error] = retrieveReferenceValues(app, newSearch);
% Checking if error was triggered
if error(1) || error(2)
% If something failed, setting the value as NaN
yAxis(:,i) = [];
xlabs(i) = [];
xAxis(i) = [];
else %Yay good to go for interpolation
if special
info.per = newSearch(3:4);
end
[kTs] = linInterpolation(app, kTvalues, info);
yAxis(:,i) = [kTs.s1x; kTs.s2x; kTs.tyx; kTs.txx];
end
end
% GRAPHING STARTS HERE
% S1
plot(app.UIAxesS1, xAxis, yAxis(1,:), 'k*--');
title(app.UIAxesS1, []);
xlabel(app.UIAxesS1, xlab);
ylabel(app.UIAxesS1, 'Kt Values');
xticks(app.UIAxesS1, xAxis);
app.UIAxesS1.XAxis.TickLabels = xlabs;
text(app.UIAxesS1, xAxis - 0.1, yAxis(1,:) + 0.3, num2cell(round(yAxis(1,:),2)));
app.UIAxesS1.YDir = 'normal';
ylim(app.UIAxesS1, [min(yAxis(1,:)) - 0.5, max(yAxis(1,:)) + 0.5]);
xlim(app.UIAxesS1, [min(xAxis) - 0.5, max(xAxis) + 0.5]);
% S2
plot(app.UIAxesS2, xAxis, yAxis(2,:), 'k*--'); % to plot the data in xAxis and yAxis variables
title(app.UIAxesS2, []); % Removing title, adding axis labels
xlabel(app.UIAxesS2, xlab);
ylabel(app.UIAxesS2, 'Kt Values');
xticks(app.UIAxesS2, xAxis); % Changing ticks and tick labels for xAxis
app.UIAxesS2.XAxis.TickLabels = xlabs;
text(app.UIAxesS2, xAxis - 0.1, yAxis(2,:) + 0.3, num2cell(round(yAxis(2,:),2))); %Adding data labels
app.UIAxesS2.YDir = 'normal'; %Flipping direction of the y axis
ylim(app.UIAxesS2, [min(yAxis(2,:)) - 0.5, max(yAxis(2,:)) + 0.5]); %Refining the limits of the axis
xlim(app.UIAxesS2, [min(xAxis) - 0.5, max(xAxis) + 0.5]);
% TY
plot(app.UIAxesTY, xAxis, yAxis(3,:), 'k*--');
title(app.UIAxesTY, []);
xlabel(app.UIAxesTY, xlab);
ylabel(app.UIAxesTY, 'Kt Values');
xticks(app.UIAxesTY, xAxis);
app.UIAxesTY.XAxis.TickLabels = xlabs;
text(app.UIAxesTY, xAxis - 0.1, yAxis(3,:) + 0.3, num2cell(round(yAxis(3,:),2)));
app.UIAxesTY.YDir = 'normal';
ylim(app.UIAxesTY, [min(yAxis(3,:)) - 0.5, max(yAxis(3,:)) + 0.5]);
xlim(app.UIAxesTY, [min(xAxis) - 0.5, max(xAxis) + 0.5]);
% TX
plot(app.UIAxesTX, xAxis, yAxis(4,:), 'k*--');
title(app.UIAxesTX, []);
xlabel(app.UIAxesTX, xlab);
ylabel(app.UIAxesTX, 'Kt Values');
xticks(app.UIAxesTX, xAxis);
app.UIAxesTX.XAxis.TickLabels = xlabs;
text(app.UIAxesTX, xAxis - 0.1, yAxis(4,:) + 0.3, num2cell(round(yAxis(4,:),2)));
app.UIAxesTX.YDir = 'normal';
ylim(app.UIAxesTX, [min(yAxis(4,:)) - 0.5, max(yAxis(4,:)) + 0.5]);
xlim(app.UIAxesTX, [min(xAxis) - 0.5, max(xAxis) + 0.5]);
end
This section below is problematic. Presumably one of your cases is the underscore character "_" because that's the only thing the switch-case is looking for and you didn't report any errors so the swich-case must be selecting one of the cases since there are variables later in the code that are dependent on those cases. Please read how to use a swich-case becase this looks like a major flaw.
switch '_' % <------ problem
case ...
case ...
case ...
end
There are other areas of concern but that one stuck out.
From App Designer, select your axes and then select the "Rulers" from the propery inspector dropdown list. Check that your YLimMode is set to "auto" (and x/z lim while you're at it).
I'm assuming you've tried shutting down your app, clearing everything, and then restarting it.
The entire function is only called if an underscore is detected within the searchString string (I know there are better ways to do this, I need to have a good cleaning/optimization session since it looks very bad haha), the smallest y-axis occurs when
case searchString(3)
is the match.
All the limit modes are set to auto
Graphs9.JPG
Yes over the last few weeks I had the standard cases where this happens (so it has been shut down and reset many time) but I could live with them, then I added the searchString(3) case which is the illegible one
Upon further examination it looks like the issue is stemming from switching between images and graphs using the same set of UIAxes, and since I originally programmed the app to only display images I had some residual code that apparently interfered (I deleted it from a different part of the app and now my images are screwed up but my graphs are not, which I should be able to fix). Thank you Adam for looking at my code I am sorry that it was such a silly error, I sincerely appreciate getting another set of eyes to make sure I wasn't being stupid in a different way.
For anyone coming across this later, I haven't tested it yet but I am guess that I will either end up
a. Overlapping two UIAxes and toggling visibility to fake the functionality
or
b. Just having two different areas for images and graphs
"The entire function is only called if an underscore is detected within the searchString string "
1) I gather that "searchString" is always one of the follow forms
  • _ABC For case 1
  • A_BC for case 2
  • AB_C For case 3
  • ABCDE_F 6
  • ABCDEF_G 7
  • ABCDEFGHI_J 10
A more readable way of doing that would be to find the index of the underscore
switch strfind(searchString,'_')
case 1
case 2
case 3
...
otherwise
error('Unexpected underscore location.')
end
2) Another thing that makes it difficult to follow your code are the non descriptive variable names that I'm sure mean something to you but "special", "str" and "xAxis" etc wouldn't communicate much to anyone else reading the code (I hope you know this is all constructive feedback). In fact the "xAxis" and "yAxis" are really hard to accept since they don't refer to an axis at all.
3) Looking at the 3rd case (only), the loop can be vectorized but it would probably be easer to read as a loop so I'll leave it.
4) Instead of length(), use numel(). (just for best-practice)
5) Avoid using common Matlab function names as variables.
[kTvalues, ~, ~, error] = retrieveReferenceValues(app, newSearch);
% |-----| I suggest changing this var name
6) see comments below; also I'm assuming there are no "error" values here since that would clear your data. Right?
if error(1) || error(2)
% If something failed, setting the value as NaN
% |--------------------------------------------| Good idea
yAxis(:,i) = []; % }
xlabs(i) = []; % }
xAxis(i) = []; % }
else
% Make them NaNs to avoid error here:
% plot(app.UIAxesS1, xAxis, yAxis(1,:), 'k*--');
7) when the plotting begins, have you verfied that
  • xAxis equals [20 30 40 50 60 70 80] ?
  • yAxis is not all 0s ?
8) is this really needed? app.UIAxesS1.YDir = 'normal';
I haven't seen anything in your code that would collapse the y axis. The screen shots of the axis parameter values also look OK so this is puzzling. If you can create a super easy way to run the app with a push of a button, along with loaded data that recreates the problem, I could step through it.

Sign in to comment.

 Accepted Answer

Samuel Nelson
Samuel Nelson on 25 Jul 2019
Edited: Samuel Nelson on 25 Jul 2019
TL:DR using the same UIAxes to swap between images and graphs can seem to cause formatting errors when using the space filling code from
https://www.mathworks.com/matlabcentral/answers/360670-imshow-in-app-designer-image-size-doesn-t-fit
I will be using visibility toggling to achieve a similar effect

1 Comment

Adam Danz
Adam Danz on 25 Jul 2019
Edited: Adam Danz on 25 Jul 2019
But you aren't using imshow(). In the code you shared, you're only using plot() and your screenshots appear to only contain plot() objects. Plot() doesn't resize the axes the same way imshow() does.
I also see that you're flipping the "Ydir" on all axes to "normal" which doesn't need to be done with plot() but it is commonly done wiht imshow(). That suggests that there's more to your code than you're sharing which would make it impossible for an outsider to debug. So I'm confused.

Sign in to comment.

More Answers (1)

Hello,
If it can help, I solved my almost same issue by changing in propreties section "viewing angle" the setting "CameraViewAngleMode". I set it to "auto"
Good luck <3

Categories

Products

Release

R2018b

Community Treasure Hunt

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

Start Hunting!