MATLAB: Does imshow image shift the other plots and text on the UIAxes in app designer

appdesignerimageimshowMATLABmoveplotsratioshift

I am running into an issue while trying to show image in an app-designer, below is my chronological workflow in my UIAxes:
Plot a square using the 'patch' function and the desired coordinates
Print text next to the square with the 'text' function
Show an image with the 'imshow' function next to the text
For some reason, showing the image messes everything up; the text shifts upwards and the square changes size. My desired result is the following: the user presses a button and a square, text, and the image appear on the plot all in a neat line. What is going on and how do I fix it?

Best Answer

When 'imshow' is called, it rearranges a few of the axes properties of app.UIAxes. It changes the direction of the y-axis ('YDir'), the modes of both the aspect ratios ('PlotBoxAspectRatioMode' and 'DataAspectRatioMode'), and the values of the aspect ratios ('PlotBoxAspectRatio' and 'DataAspectRatio'). We will need to preserve the original values and reassign them after 'imshow' is called.
The first row of pixels within an image is normally at the top. By default, the 'imshow' function inverts the y-axis direction when the image is displayed on an axes by setting the 'YDir' property to 'reverse.' To revert the y-axis direction after calling 'imshow', set the 'YDir' property to 'normal'. Then, to preserve the orientation of the image, flip the image using 'flip'.
Next, the 'imshow' function sets the 'DataAspectRatioMode' property of app.UIAxes to 'manual' and the 'PlotBoxAspectRatioMode' to 'auto'. The 'DataAspectRatio' property of app.PlotLegend is then rearranged to match the ratio of the image, and the 'PlotBoxAspectRatioMode' modifies itself accordingly.
In the code below, the original 'PlotBoxAspectRatio' is preserved, then the 'PlotBoxAspectRatioMode' is set to 'manual' while the 'DataAspectRatioMode' is set to 'auto'. Finally, the 'PlotBoxAspectRatio' is reassigned to the property's original value and the 'DataAspectRatio' property modifies itself accordingly.
% Button pushed function: Button
function ButtonPushed(app, event)
v = [60,0; 75,0; 75,2; 60,2];
f = [1, 2, 3, 4, 1];
sqHandle = patch(app.UIAxes,'vertices', v, 'faces', f, ...
'FaceColor', 'k', 'LineStyle', 'none');
txtHandle = text(app.UIAxes, 80, 0, 'test text','Fontsize',12,'VerticalAlignment', 'bottom');
hold(app.PlotLegend,'on');
pbarOriginal = pbaspect(app.UIAxes); % preserve the original PlotBoxAspectRatio
I = imread('myImage.jpg');
I = flip(I); % flip the image
imshow(I,'Parent',app.UIAxes,'XData',[90,95],'YData',[0,2]);
% Revert the properties back to their original values
app.UIAxes.YDir = 'normal';
app.UIAxes.PlotBoxAspectRatioMode = 'manual';
app.UIAxes.DataAspectRatioMode = 'auto';
app.UIAxes.PlotBoxAspectRatio = pbarOriginal;
end