rescaling of imagesc in app.UIAxes
Show older comments
Hi, I have heatmap data with 16384 rows and 61 columns. This represents spectrogram data from 0-10000Hz over 6.1s. I would like to "rescale" the image in a way, that the Y-Axis does not display the data from 0-16384 but from 0-10000 (Hz). When I use the code snipet below in a random script, this works as expected.
A = rand(16384,61);
B = imagesc(linspace(0,61,62),linspace(0,10000,10001),A);
set(gca,"YDir", "normal");
The ticks now go from 0-10000Hz, full picture is visible, single pixels have a height of about 0.61Hz.
When I try to recreate this exact behavior in my app, the individual pixel height goes to double that, 1.22Hz.
function SelectFileButton_2Pushed(app, event)
HeatMap = rand(16384,61);
imagesc(app.UIAxes2, linspace(0,61,62), linspace(0,10000,10001), HeatMap);
app.UIAxes2.YDir = 'normal';
end
I can not explain this behavior. UIAxes2 is just a plain axis I inserted, did not change anything on it.
5 Comments
dpb
on 29 May 2026
How did you determine this? The resolution of the data is unchanged regardless of the graphics rendering.
I would venture perhaps the uifigure/axes is smaller in the app to make room for other app controls, etc., and so the number of pixels on the screen dedicated to the axes had to be reduced.
But, I think we would need more details of what you're looking at specifically to draw any definite conclusions.
Have you looked at the image CData to compare?
Back to my first wondering -- it does appear the app image is shorter; can you adjust it to the same height as the standalone and see if that does affect the rendering?
Or, conversely try the standalone (also with a uifigure as the parent) at the height of the axes in the app...
dpb
on 29 May 2026
"...seems as the resolution is downsampled on purpose."
Back to Q? about physical display/height -- how many physical pixels are there in the app y-axes range between the two plots? Would seem with modern displays there would be more than sufficient but wondering if there is some magic number that causes such behavior. Although this is, agreed, grasping at straws.
"...how to extract the CData from the app side"
The most direct route would be to assign to an output variable when call imagesc() -- which I see you used B
CD=B.CData;
...
Alternatively, of course, you can retrieve it as the child of the axes.
The other thing to look at is what clim (caxis prior releases, deprecated beginning R2022, not sure when removed) returns.
The last straw I can think of would be to try the low-level version and see it that makes any difference...
X=linspace(0,61,62); Y=linspace(0,10000,10001); % for convenience only
B = imagesc('XData',X,'YData',Y,'CData',A);
...
It may be this will have to go to Mathworks as an official support request if none of these avenues pan out.
Answers (1)
I built a minimal app in R2021b AppDesigner that just added the image to an axis in the startup function. It appears the same as interactive plot does. See if you can do the same thing locally...if so, it'll be something else going on in your axes somehow.

The guts of the app code are below...I didn't change anything from just adding an axes so the labels, etc., are still default. But, adding the data as imagesc to the UIFigure axes seemed to work just fine.
I just copied/pasted from your example above, one slight change I'd make that isn't anything except form would be to write
app.UIAxes.YDir='normal';
instead of calling set.
Tthing that caught my eye that I had overlooked before is using gca instead of the saved handle in an app because it will not return a the UIAxes but would create another regular axes object if none exists. Not sure that has any bearing here as it wouldn't appear that the set call would then be addressing the UIAxes at all. But, using explicit handles is particularly important in apps that are not sequential code used to writing at the command line; context can change behind your back.
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
A = rand(16384,61);
X=linspace(0,61,62);
Y=linspace(0,10000,10001);
B = imagesc(app.UIAxes,X,Y,A);
set(app.UIAxes,"YDir", "normal");
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure and hide until all components are created
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Position = [100 100 640 480];
app.UIFigure.Name = 'MATLAB App';
% Create UIAxes
app.UIAxes = uiaxes(app.UIFigure);
title(app.UIAxes, 'Title')
xlabel(app.UIAxes, 'X')
ylabel(app.UIAxes, 'Y')
zlabel(app.UIAxes, 'Z')
app.UIAxes.Position = [68 180 300 185];
% Show the figure after all components are created
app.UIFigure.Visible = 'on';
end
6 Comments
info = rendererinfo(gca)
info.Details
And there is the renderer texture limit.
Alexander
on 1 Jun 2026
Alexander
on 1 Jun 2026
I didn't test it, but see if remove the UIAxes from the app but add creation of regular axes in the startup function.
% Code that executes after component creation
function startupFcn(app)
% Create normal Axes instead of using UIAxes
app.Axes = axes(app.UIFigure);
title(app.Axes, 'Regular Axes')
%xlabel(app.Axes, 'X')
%ylabel(app.Axes, 'Y')
%zlabel(app.Axes, 'Z')
app.Axes.Position = [68 180 300 185];
% add image to the regular axes object...
A = rand(16384,61);
X=linspace(0,61,62;
Y=linspace(0,10000,10001);
B = imagesc(app.Axes,X,Y,A);
app.Axes.YDir='normal';
end
This should determine if it's something peculiar to the UIAxes in the app or whether it is fundamental to the rendering -- either inside the engine itself or logic in MATLAB internally would still be to be resolved..
Categories
Find more on Develop uifigure-Based Apps 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!




