MATLAB Answers

Set aspect ratio in tilelayout

17 views (last 30 days)
Joseph Pedersen
Joseph Pedersen on 16 Sep 2020
Edited: Adam Danz on 21 Sep 2020
When I run this code, the two plots are not each "square" (aspect ratio 1:1)
function [] = plotSVD( A )
A = [1, 2; 0, 2];
theta = linspace(0,2*pi, 1000);
x1 = cos(theta);
y1 = sin(theta);
tempBecauseMatlabIsStupid = A*[x1;y1];
x2 = tempBecauseMatlabIsStupid(1,:);
y2 = tempBecauseMatlabIsStupid(2,:);
% Two plots
tiledlayout(1,2) % Requires R2019b or later
ax1 = nexttile;
pbaspect(ax1,[1 1 1]); % doesn't do anything
axis equal; % doesn't do anything
plot(ax1,x1,y1)
ax2 = nexttile;
pbaspect(ax2,[1 1 1]); % doesn't do anything
axis equal; % doesn't do anything
plot(ax2,x2,y2)
end
Currently, to make them "square", I have to manually adjust the width of the window.
How can I make MATLAB print them "square"? Ideally, I'd like the figure to show in a window AND save to a PDF, with each of the two plots in the figure having an aspect ratio of 1:1

  3 Comments

Adam Danz
Adam Danz on 20 Sep 2020
"axis equal; % doesn't do anything"
axis equal does exactly what it's supposed to do - it equates the length of the data units along the axes.
What you're looking for is axis square which will equate the lengths of the axes but will not equate the axis units so a circle may not appear as a circle.
If you want both, you can set axis equal and then set the ylim and xlim ranges to be the same.
Joseph Pedersen
Joseph Pedersen on 21 Sep 2020
What I want is for the aspect ratio to be 1:1
Is that what you mean by "equates the length of the data units along the axes"?
If you look below, you'll see that the aspect ratio is not 1:1, even though I used:
daspect(ax1,[1 1 1]); % doesn't do anything
pbaspect(ax1,[1 1 1]); % doesn't do anything
axis equal; % doesn't do anything
Adam Danz
Adam Danz on 21 Sep 2020
That's because you are applying it incorrectly.
"% doesn't do anything"
Those lines are doing exactly what they should be doing but you're losing those settings when you plot data to the axes.
See my answer for the correct way to apply these settings.

Sign in to comment.

Accepted Answer

Adam Danz
Adam Danz on 21 Sep 2020
Edited: Adam Danz on 21 Sep 2020
You either need to apply the settings after plotting the data or you need to execute "hold on" after applying the settings, before doing the plotting. I suggest doing the prior.
tiledlayout(1,2)
ax1 = nexttile;
plot(ax1,x1,y1)
axis equal; % <---- move to after-plot
daspect(ax1,[1 1 1]); % <---- move to after-plot
pbaspect(ax1,[1 1 1]); % <---- move to after-plot
or
tiledlayout(1,2)
axis equal;
daspect(ax1,[1 1 1]);
pbaspect(ax1,[1 1 1]);
hold on % <------- add this
ax1 = nexttile;
plot(ax1,x1,y1)
Demo: difference betwteen DataAspectRatio and Plot Box Asepct Ratio
When you set axis equal, the DataAspectRatio is set to [1 1 1] and the associated mode properties are set to manual. Also, the “stretch-to-fill” behavior is disabled. So, no need to set daspect when using axis equal.
pdadpect sets the plot box aspect ratio which is different than the DataAspectRatio. Here's a demo showing the difference:
Default axes within a figure that has been expanded horiziontally a bit. Note that the x and y ticks are the same but the grid does not form squares.
x = 1:20;
y = x*.8;
plot(x,y)
grid on
set(gca, 'XTick', 0:5:20, 'YTick', 0:5:20)
DataAspectRatio equal. Now the grid forms squares but the axis itself is not square. The x axis has a larger range than the y axis.
axis equal
Plot box aspect ratio equal. Now the axis is square as well.
pbaspect([1 1 1])
Note that this can also be achieved by setting the xlim and ylim to the same range. In fact, this method is often preferred and gives you more control over the range of values covered by the axes.
% instead of pbaspect([1 1 1])
xlim([0,20])
ylim([0,20])

  2 Comments

Joseph Pedersen
Joseph Pedersen on 21 Sep 2020
Thanks! Putting the commands after plot worked.
I'm not sure if daspect(ax1,[1 1 1]); or pbaspect(ax1,[1 1 1]); did anything. It worked with just axis equal; on the line AFTER plot.
Adam Danz
Adam Danz on 21 Sep 2020
I added to my answer to explain how axis equal and pbaspect differ. If something still doesn't make sense, I'd be happy to explain more.

Sign in to comment.

More Answers (1)

Vasishta Bhargava
Vasishta Bhargava on 17 Sep 2020
Edited: Vasishta Bhargava on 17 Sep 2020
%if true
% code
% end
tiledlayout('flow')
For keeping the aspect ratio uniform. Don't use handles to the plot function when you use this option.
%if true
% code
% end
saveas('filename','pdf');
To save the figure as PDF file. If it's in GUI use the figure handle
% if true
% code
% end
saveas(fig_handle,'filename','pdf')

  5 Comments

Show 2 older comments
Joseph Pedersen
Joseph Pedersen on 20 Sep 2020
When you run the code, is it square? When I run the code, it still is not square:
A = [1, 2; 0, 2];
% Define the unit ball in the preimage
theta = linspace(0,2*pi, 1000);
x1 = cos(theta);
y1 = sin(theta);
% Define the image of that ball
image = A*[x1;y1];
x2 = image(1,:);
y2 = image(2,:);
% Two plots
tiledlayout(1,2) % Requires R2019b or later
ax1 = nexttile;
daspect(ax1,[1 1 1]);
pbaspect(ax1,[1 1 1]); % doesn't do anything
axis equal; % doesn't do anything
plot(ax1,x1,y1)
ax2 = nexttile;
daspect(ax2,[1 1 1]);
pbaspect(ax2,[1 1 1]); % doesn't do anything
axis equal; % doesn't do anything
plot(ax2,x2,y2)
Vasishta Bhargava
Vasishta Bhargava on 20 Sep 2020
Use
% if true
% code
% end
axis square
instead of axis equal
or
% if true
% code
% end
set(gca,'position',[x,y,w,h]);
x & y are coordinates. w & h are width and height of the boxes
To set it explicitly
Joseph Pedersen
Joseph Pedersen on 21 Sep 2020
Again, I'm curious, are you saying that when you ran the code above, with "axis equal" changed to "axis square", did the images produced have an aspect ratio of 1:1?
Because when I changed both the "axis equal" to "axis square" the figure remained the same:

Sign in to comment.

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!