2

In Matlab I have a GUI that analyses and plots data on to a plot in my main figure of the GUI. I often have to plot a lot of different data sets though with it and have two main problems:

  1. I cannot set a fixed size area for the legend to be constructed in
  2. I cannot work out how to make the legend text and box scale when the GUI is full screened

One solution I was thinking about is a scroll bar in the legend, is this possible? Hopefully the image below highlights the problem:

http://i42.tinypic.com/6yyzrl.jpg

Gunther Struyf
  • 11,158
  • 2
  • 34
  • 58

1 Answers1

2

Here is a solution that will scale the legend with whatever scaling factor you desire:

close all;

% Generate data
N = 10;
T = 10;
x = rand(T, N);

% How much to scale by
xLegScale = 0.5;
yLegScale = 0.5;

% Plot some data
labels = arrayfun(@(n){sprintf('Legend Entry for Line %i', n)}, 1:N);
plot(x, 'LineWidth', 2);
hLeg = legend(labels);

% Figure out new legend width / height, including a little fudge
legPos = get(hLeg, 'Position');
widthFudgeFactor = 0.1;
legPosNew = legPos;
legPosNew(3:4) = legPosNew(3:4) .* [xLegScale yLegScale];
legPosNew(3) = legPosNew(3) * (1 + widthFudgeFactor);

% Create a new axes that matches the legend axes and copy all legend
% children to it, then delete the legend
axNew = axes('Parent', gcf);
xlim(axNew, get(hLeg, 'XLim'));
ylim(axNew, get(hLeg, 'YLim'));
box(axNew, 'on');
set(axNew, 'Position', legPosNew);
set(axNew, 'XTick', [], 'YTick', []);
copyobj(get(hLeg, 'Children'), axNew)
delete(hLeg);
hLeg = axNew;

% Find text objects inside legend
hLegTexts = findobj('Parent', hLeg, 'Type', 'text');

% Scale font size
legTextFontSize = get(hLegTexts, 'FontSize');
fszScale = mean([xLegScale yLegScale]);
legTextFontSizeNew = cellfun(@(x){fszScale * x}, legTextFontSize);
arrayfun(@(h, fontSize)set(h, 'FontSize', fontSize{:}), hLegTexts, legTextFontSizeNew);

This code creates a new axes that is a facsimile of the original legend axes and does all the position setting work on that. The reason is that the legend object doesn't like being resized smaller than it thinks it should be (presumably there is some code doing this when it resizes, but there is no ResizeFcn property for axes objects, so I can't see a way to disable this functionality aside from making a copy of the axes).

The only thing inside the axes you actually need to scale is the font size: the rest will be scaled automatically due to the use of normalized units.

If this kind of scaling solution doesn't tickle your fancy, then you could do something similar (copy the legend axes children) but add a scrollbar to the new axes (and set its units to something other than normalized so that it doesn't scale its contents when you resize it). You might draw some inspiration for how to do the scrolling from this question.

Community
  • 1
  • 1
wakjah
  • 4,541
  • 1
  • 18
  • 23