1

I have the following code:

X = 0:pi/100:0.25*pi;
Y1 = sin(X);
Y2 = cos(X);
Y3 = tan(X);
fh = figure('toolbar','none','menubar','none','Units','characters');
Pan1 = uipanel(fh,'Units','normalized','Position',[0 0 0.5 1],'title',...
  'Panel1');
Pan2 = uipanel(fh,'Units','normalized','Position',[0.5 0 0.5 1],'title',...
  'Panel2');
haxes = axes('Parent',Pan2,'Units', 'normalized','Position',...
[0.125 0.1 0.75 0.75]);
hplot = plot(haxes,X,Y1,X,Y2,X,Y3);
xlabel(haxes,'Time (second)');
ylabel(haxes,'Amplitude (meter)');
title(haxes,'Trigonometric functions');
Ley = {'Sine function','Cosine function','Tangent function'}; %# legend's strings values
legend(haxes,Ley,'Location','SouthOutside');
[FileName,PathName,FilterIndex] = uiputfile('*.bmp;*.png;*.jpg;*.tif','Save as');
ftmp = figure('Menu','none','Toolbar','none','Units','normalized',...
  'Position',[-1000 -1000 1 1]);
set(gcf,'PaperPositionMode','auto');
set(gcf,'InvertHardcopy','off');
new_axes = copyobj(haxes, ftmp);
legend(new_axes,Ley,'Location','SouthOutside','FontSize',8);
set(new_axes,'Units','normalized','Position',[0.1 0.1 0.8 0.8]);
fmtgraf = {'-dbmp','-dpng','-djpeg','-dtiff'};
fmt = fmtgraf{FilterIndex};
print(ftmp,fmt,FileName,'-r0');
delete(ftmp);
delete(fh);

As seen in the code, the command line

legend(new_axes,Ley,'Location','SouthOutside','FontSize',8);

is run before the command line

 set(new_axes,'Units','normalized','Position',[0.1 0.1 0.8 0.8]);

Because of it, the image appears cutted by its low part as seen below (independently of the existence or no existence of the property/value 'FontSize')

If the command line

 legend(new_axes,Ley,'Location','SouthOutside','FontSize',8);

is run after the command line

 set(new_axes,'Units','normalized','Position',[0.1 0.1 0.8 0.8]);

now the image is cutted by its low part but in this case it is not seen neither the xlabel text nor the legend box (as seen below)

If 'FontSize',8 is suppressed, all is Ok. How can I fix this if I want that the legend to have a lesser size?

julianfperez
  • 1,726
  • 5
  • 38
  • 69

2 Answers2

2

It works fine for me too... You have to understand that LEGEND basically creates another axis instance inside the figure.

Now you are placing it using 'SouthOutside' location, so it will try to resize the existing axis to place itself underneath it, but if you don't leave it enough space it might not fit, especially as you are using 'normalized' units which let the axes auto-resize given the parent container size.

Try to vertically shrink the main plot axis a bit in advance, to give the legend more room...

Also the order of commands does matter. Compare this:

new_axes = copyobj(haxes, ftmp);
legend(new_axes, Ley, 'Location','SouthOutside', 'FontSize',8);
set(new_axes, 'Units','normalized', 'Position',[0.1 0.1 0.8 0.8]);

against:

new_axes = copyobj(haxes, ftmp);
set(new_axes, 'Units','normalized', 'Position',[0.1 0.1 0.8 0.8]);
legend(new_axes, Ley, 'Location','SouthOutside', 'FontSize',8);

EDIT:

As I mentioned, LEGEND creates just another axis. Therefore for ultimate control, you could manually position all the axes in the figure yourself (specify actual positions instead of relying on "outside" values for the 'Location' property exposed by the legend function).. Here is an example to illustrate:

%# create a normal plot
clf
hAx = axes();
plot(hAx, rand(10,3))
xlabel(hAx, 'xlabel'), title(hAx,'title')

%# add a legend on the inside and record the axis outerposition (in pixels)
hLgnd = legend(hAx, {'1' '2' '3'}, 'Location','South', 'FontSize',8);
set(hLgnd, 'Units','pixels')
op = get(hLgnd,'OuterPosition');
set(hLgnd, 'Units','normalized')

%# resize the plot axis vertically to make room for the legend
set(hAx, 'Units','pixels')
pos = get(hAx,'Position');
ins = get(hAx,'TightInset');
set(hAx, 'Position',[pos(1) pos(2)+op(4) pos(3) pos(4)-op(4)])
set(hAx, 'Units','normalized')

%# move the legend to the bottom in the free space
set(hLgnd, 'Units','pixels')
set(hLgnd, 'OuterPosition',[op(1) (pos(2)-ins(2))/2 op(3) op(4)])
set(hLgnd, 'Units','normalized')

screenshot

Try it out for different figure sizes and rerun the code.. Note that if you want the axes to correctly adjust their sizes automatically when you resize the figure, you have to do a similar thing as the above code inside the 'ResizeFcn' event handler of the figure, ie:

set(gcf,'ResizeFcn',@myEventHandler)
Amro
  • 123,847
  • 25
  • 243
  • 454
  • Thank you for your answer. I have done some proofs based on it and I have edited my question to include them. I think (although I am not sure) my problem has two causes: my widescreen size and the change of the property 'FontSize'. Respect to the latter, the Matlab documentation help says that "The font size and font name for the legend strings match the axes FontSize and FontName properties". So, if I change it through the command legend, then the axes' FontSize also changes. – julianfperez Nov 22 '11 at 23:39
1

It works fine for me:

Result

I notice that our screenshots have different aspect ratios. Perhaps your monitor has a widescreen aspect ratio? The 'units' 'normalized' option that you're applying to the new axes will set its dimensions relative to the monitor it's displayed on. When you create a wider figure, perhaps MATLAB is clipping the legend from the bottom (its graphics aren't perfect).

My advice would be to perhaps try setting the axes units directly using 'units' 'pixels', with a squarer aspect ratio.

Another option might be to create the legend with 'orientation' 'horizontal', which would spread the items out with less height, or to place it inside the graph, perhaps 'SouthEast'.

Sam Roberts
  • 23,951
  • 1
  • 40
  • 64
  • Thank you for your answer. Yes, you are right: my monitor has a wide screen. As I have already mentioned in the reply comment for @Amro, after some proofs, I think the FontSize property along with the widescreen size can be the problem's sources. – julianfperez Nov 22 '11 at 23:52