0

複数列の凡例を作成できる CLegend というアプリケーションを設計しました。コードは

function CLegend(hax,numcol,Ley)
%# Inputs
% hax : handle of the axes object to which belongs the legend
% numcol: number of columns for the legend
% Ley: text strings (labels) for the legend

set(hax,'Units','normalized','Position',[0.1 0.1 0.8 0.8]);
set(hax,'Units','characters');
posAx = get(hax,'Position');
insAx = get(hax,'TightInset');

[legend_h,object_h] = legend(hax,Ley,'Units','characters','Location',...
    'South','Orientation','vertical');
posl = get(legend_h,'Position');
numlines = length(Ley);
if (numlines<numcol)
    numcol = numlines;
end

numpercolumn = ceil(numlines/numcol);

if (mod(numlines,numpercolumn) == 0)
    numcol = numlines/numpercolumn;
end

l = zeros(1,numlines);
a = zeros(1,numlines);
h = zeros(1,4);
for j=1:numlines
    h = get(object_h(j),'Extent');
    l(j) = h(3);
    a(j) = h(4);
    set(object_h(j),'Units','characters');
end

lmax = posl(3)*max(l);
hmax = posl(4)*max(a);
hLine = object_h(numlines+1);
xdata = get(hLine, 'xdata');
dx = xdata(2)-xdata(1);
di = 2;

sheight = hmax;     
height = hmax*numpercolumn-sheight/2;            
line_width = dx*posl(3);                
spacer = xdata(1)*posl(3);              
delta1 = spacer + line_width + spacer + lmax;
delta2 = line_width + spacer + lmax + spacer;
delta3 = lmax + spacer + line_width + spacer;
factx = 1/(posl(3)*numcol);
facty = 1/(hmax*numpercolumn);
width_l = numcol*delta1;

set(legend_h, 'Position', [posAx(1) + 0.5*(posAx(3)-width_l) posl(2) ...
   width_l  numpercolumn*hmax]);

col_ind = -1;
row_ind = -1;
j = 0;
for i=1:numlines,

    if strcmpi(orient,'horizontal'),
        if mod(i,numcol)==1,
            row_ind = row_ind+1;
        end
        col_ind = mod(i,numcol)-1;
        if col_ind == -1,
             col_ind = numcol-1;
        end

    else
        if numpercolumn==1 || mod(i,numpercolumn)==1,
            col_ind = col_ind+1;
        end

        row_ind = mod(i,numpercolumn)-1;
        if row_ind == -1,
             row_ind = numpercolumn-1;
        end   
    end

    if (i==1)
        linenum = i+numlines;
    else
        linenum = linenum+di;
    end
    labelnum = i;

    set(object_h(linenum), 'ydata',facty*[height-row_ind*sheight ...
        height-row_ind*sheight]);
    set(object_h(linenum), 'xdata', factx*[spacer + j*delta2 ...
                spacer + j*delta2 + line_width]);
    set(object_h(linenum+1), 'ydata',facty*(height-row_ind*sheight));
    set(object_h(linenum+1), 'xdata', factx*(spacer+line_width/2));
    set(object_h(labelnum), 'Position', [j*delta3+spacer*2+line_width ...
        height-row_ind*sheight]);
    if (mod(i,numpercolumn)== 0)
        j = j + 1;   
    end
end
opl = get(legend_h,'OuterPosition');
set(hax, 'Position',[posAx(1) posAx(2)+opl(4) posAx(3) posAx(4)-opl(4)]);

set(legend_h, 'OuterPosition',[opl(1) (posAx(2)-insAx(2))/2 opl(3) opl(4)]);
set([hax,legend_h],'Units','normalized');
end

問題があります。より複雑なコードで試してみましたが、以下に示すものと似ています。

function qq
fh = figure('Units','characters');
GrapWin = uipanel ('Parent',fh,'Units','characters','title','Graphic',...
    'Position',[135 5 120 40]);
haxes = axes('Parent',GrapWin,'Units','normalized','Position',[0.1 0.1 0.8 0.8]);
PanVD = uipanel('Parent',fh,'Units','characters','Position',[55 5 30 10],...
    'title','Dependent Variable');
VDlh = uicontrol('Parent',PanVD,'Style','listbox','Units',...
    'normalized','Position',[0 0 1 1],'String',{'X','Y','Z'},'Value',1,...
    'Callback',@VDLhCallback);
T = 0:pi/100:2*pi;
X = sin(T);
xlabel(haxes,'Time');
title(haxes,'Sine Function');
plot(haxes,T,X);
CLegend(haxes,3,{'Var X'});

function VDLhCallback (src,evt)
    value = get(VDlh,'Value');
    switch value
        case 1
        title(haxes,'Sine Function');
        plot(haxes,T,X);
        CLegend(haxes,3,{'Var X'});   
        case 2
        title(haxes,'Cosine Function');
        Y = cos(T);
        plot(haxes,T,Y);
        CLegend(haxes,3,{'Var Y'});   
        case 3
        Z = tan(T);
        title(haxes,'Tangent Function');
        plot(haxes,T,Z);
        CLegend(haxes,3,{'Var Z'});     

    end

end

end

CLegend が初めて呼び出されたときに凡例が中央に表示されず (軸に関して)、リストボックス オプションを介した次の呼び出しが中央に表示されるため、理解できないことが起こります。発生するその他の問題は、コマンド ライン set(haxes,'Units','normalized') を削除すると、凡例は中央に配置されますが、軸のサイズが縮小されて表示されることです。また、Clegend が初めて呼び出されたときに、軸の位置 (変数 posAx) が次の呼び出し (posAx は常に同じ) とは異なることもわかりました。単位を変えても物体の位置は変わらないと思っていたのですが、この問題は頭の中で疑問に思っています。

4

2 に答える 2

1

Figure Properties documentationでは、次のように述べられていますUnit

このプロパティは、CurrentPoint および Position プロパティに影響します。Units の値を変更する場合は、Units がデフォルト値であると想定する他の関数に影響を与えないように、計算が完了した後でデフォルト値に戻すことをお勧めします。

あなたの問題を説明できますか?

于 2011-12-05T12:26:17.147 に答える
0

多くの証明の後、私の問題は図のサイズ変更であることがわかりました。CLegend が初めて呼び出されたとき、Figure ウィンドウは元のサイズでした。次の CLegend の呼び出しは、Figure ウィンドウが最大化された状態で行われました。

于 2011-12-07T18:09:59.867 に答える