Set the Subplot Apsect Ratio Manually

hi, I have a problem with setting the AR of one of my subplots. lets try to make this more understandable. first of all, here is a part of the code
scrsz = get(0,'ScreenSize');
figure('Position',[1 scrsz(2) scrsz(3) scrsz(4)]);
s1=subplot(2,6,1:5); hold on; grid on; box on; axis([totminx 1.02 totminz totmaxz]);
dx=1.02-totminx;
dz=totmaxz-totminz;
h=0.3412;
w=h*dx/dz;
set(s1,'FontSize',15, 'Position', [0.13 ,0.5838 ,w ,h])
plot(poly(:,1), poly(:,2), 'k', 'LineWidth', 2)
plot(x1, z1, 's', 'MarkerFaceColor', 'r', 'MarkerEdgeColor', 'r', 'MarkerSize', 5);
ok, what i want to get is original proportions for the plot, meaning that the dist between 0-0.1 will look the same in the x and y axis. (does not mean a square image!)
also, i want to do this manually by changing the position of the subplot itself.
i want to do this because when i use the simple way of: set(s1, 'DataAspectRatio', [ 1 1 1]) other annotations that i add afterwards are not connected and seem to be floating, this is because the "DAR" doesn't change the subplot's position.
hope that you can at least understand my question now :( sorry about the confusion caused.
thanks Noa

5 Commenti

Using axis equal adjusts the limits on the x and y (and possibly z) dimensions. It doesn't change the size/position of the subplot. What exactly doesn't work with set(gca, 'Position', [x,y,w,h])
noa
noa il 19 Set 2012
if i have axis([xmin xmax ymin yamx])
h=0.3412;
set(gca, 'Position', [0.13 ,0.5838 ,w ,h])
how do i set w so that I get AR of 1:1
Malcolm Lidierth
Malcolm Lidierth il 19 Set 2012
Modificato: Malcolm Lidierth il 19 Set 2012
@noa As you have, but do not used normalised units - Use centimeters etc instead.
set(gca, 'Units', .....
noa
noa il 19 Set 2012
but all of my other subplots are already set by the normalized units.
as @Daniel said, it doesn't change the position of the subplot, and that is what I want
At this point I am going to flag this question. Noa, please edit the question to provide some code and ideally an image that demonstrates the problem and a clear and concise explanation of what you see and what you expect to see.

Accedi per commentare.

 Risposta accettata

José-Luis
José-Luis il 19 Set 2012
Modificato: José-Luis il 19 Set 2012
That would depend on the aspect ratio of your figure box, for instance:
h = figure;
pos = get(h,'Position');
ratio = pos(3) / pos(4);
a = plot(rand(10,1));
aH = ancestor(a,'axes');
desiredWidth = 0.6; %for example
desiredHeight = desiredWidth * ratio;
posA = get(aH,'Position');
posA(3) = desiredWidth;
posA(4) = desiredHeight;
set(aH,'Position',posA);
Will give you a square plot. You would need to recalculate every time you resize your figure. Also, the desired width has to be selected such that you do not overstep the boundaries of your figure box. It should work for a subplot as well, you just have to be careful with desiredWidth.
ADD Say you know in advance your xlim and ylim (or you get them afterwards), maybe this is what you are looking for:
xlim = [0 5];
ylim = [0 10];
ratio = diff(xlim)/diff(ylim);
h = plot( 1:10);
aH = ancestor(h,'axes');
axis equal;
set(aH,'PlotBoxAspectRatio',[1 ratio 1])
set(aH,'XLim',xlim,'YLim',ylim);

8 Commenti

this isn't working... seems to give me a 1:2 ratio. meaning that i get a square grid but for 0.2 in x direction it only gets 0.1 in the z dir i'll give you my code partially (prior to the solution suggested) maybe it can help:
scrsz = get(0,'ScreenSize');
figure('Position',[1 scrsz(2) scrsz(3) scrsz(4)]);
s1=subplot(2,6,1:5); hold on; grid on; box on;
axis([totminx 1.02 totminz totmaxz]);
pos=get(s1, 'Position');
ratio=pos(3)/pos(4);
dx=1.02-totminx;
dz=totmaxz-totminz;
h=0.3412;
w=h*dx/dz;
set(s1,'FontSize',15, 'Position', [0.13 ,0.5838 ,0.795 ,h])
plot(poly(:,1), poly(:,2), 'k', 'LineWidth', 2)
plot(x1, z1, 's', 'MarkerFaceColor', 'r', 'MarkerEdgeColor', 'r', 'MarkerSize', 5);
draw_PFC(configuration, chord, poly(end-1:end, 1:2), coordinates)
for i=1:45
if flag(i,j)
x=[x2(i,j) x1(i,j)];
z=[z2(i,j) z1(i,j)];
else
x=[x1(i,j) x2(i,j)];
z=[z1(i,j) z2(i,j)];
end
[xf zf]=ds2nfu(x,z);
%transfer from image units to normalized units
ah=annotation('arrow', xf, zf, 'HeadStyle', 'vback1', 'Units', 'centimeters');
if flag(i,j)
set(ah,'Color', 'b');
end
end
ratio=pos(3)/pos(4);
That should be:
scrsz(3) /scrsz(4)
and if
h = your_value
then
w = h / ratio;
noa
noa il 19 Set 2012
the same problem occurs. I get a square, but in grid unit in the x it is once for 0.2 and in y once for 0.1. I know it is wrong because if I type after that set(gca, 'DataAspectRatio', [1 1 1]) it changes the size of the plot.
Well, I don't get it. If you want to change the aspect ratio of your subplot you need to change its size. Or am I missing something?
noa
noa il 19 Set 2012
i want to change size, but my logic, and tell me if i am wrong, is:
if i set a certain aspect ratio which i think should give me 1:1, and the set the 'DataAspectRatio' option, which does that automatically.
--> if the image doesnt change size - it means that i got the 1:1 AR correct
--> if it does change size, it means that i got it wrong
right?
José-Luis
José-Luis il 19 Set 2012
Modificato: José-Luis il 19 Set 2012
I think you might be confused about what DataAspectRatio is:
DataAspectRatio [dx dy dz]
Relative scaling of data units. Controls the relative scaling of data units in the x, y, and z directions. For example, setting this property to [1 2 1] causes the length of one unit of data in the x-direction to be the same length as two units of data in the y-direction and one unit of data in the z-direction.
It has nothing to do with the size of your axes.
You can control that with, as Daniel suggested, PlotBoxAspectRatio. Or by manipulating your axes sizes. Since the axes size is defined in terms of the figure box, you need to know the size of the figure box in order to obtain square axes (if you want to set them manually, that is), which is what I suggest in my answer.
noa
noa il 19 Set 2012
this is what it looks like at the moment, the AR is ok,.... but now the arrow annotations are floating!
José-Luis
José-Luis il 19 Set 2012
Modificato: José-Luis il 19 Set 2012
Annotations are defined with respect to the figure box, not to the axes limits. It should be posssible to rescale, but it would be rather convoluted. In your case, it would involve translation and shear, you could get the transformation matrix using the position (->translation) and scale (-> shear) of your original and final axes (in "figure" units), then multiply the starting and ending coordinates of your arrows by the transformation matrix and then redraw). As i said, convoluted.
It looks like you are ploting tangent vectors. Maybe, it would be better to use the quiver built in function. That would save some headaches.
Or maybe I am still missing the point and there is a simpler answer.

Accedi per commentare.

Più risposte (2)

I think what you are looking for is:
set(gca, 'PlotBoxAspectRatio', [1,1,1])

1 Commento

noa
noa il 19 Set 2012
no... this is not good since it does not change the 'Position' of the subplot, so afterwards when I add arrow anntations they seem to be floating in the screen with no relation to the plot itself

Accedi per commentare.

Daniel Shub
Daniel Shub il 19 Set 2012
Modificato: Daniel Shub il 19 Set 2012
I think the problem is that the default unit of an axis object is normalized and the default unit of a figure object is pixels. This means that if the figure is not square than an axis with a position of [x, y, a, a] will not be square. If you want an axis with a position of [x, y, a, a] to be square, or more accurately if you want [x, y, a, b] to have an aspect ratio of a/b, then you need a square figure. Assuming that get(0, 'MonitorPositions') returns something meaningful (see: dual monitor support), then you should be able to do
pos = get(0, 'MonitorPositions');
set(gcf, 'Position', [1, 1, 0.5*min(pos(1, 3:4)), 0.5*min(pos(1, 3:4))]);
set(gca, 'Position', [0.1, 0.1, 0.8, 0.8]);
While I agree that afterwards a set(gca, 'PlotBoxAspectRatio', [1,1,1]), should have no effect, on my system it does. There is a slight change in the tight inset, but I don't think this affects the size of the axis directly.

4 Commenti

noa
noa il 19 Set 2012
maybe i don't explain something correctly, i don't need a square figure... all i need is that the "distance" will x will appear the same as the "distance" in y, to get true proportions
José-Luis
José-Luis il 19 Set 2012
Modificato: José-Luis il 19 Set 2012
axis equal
noa
noa il 19 Set 2012
this changes the xlim and ylim i have set. i don't want that
If you don't want to change xlim and ylim, see my edited answer.

Accedi per commentare.

Categorie

Community Treasure Hunt

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

Start Hunting!

Translated by