5

この問題は unix matlabs のみで発生し、Windows ユーザーは再現できません。

y 軸ラベルの上にあるデータヒントを作成しようとしているときに問題が発生しています。次の図は、この問題を示しています。

問題の例

ご覧のとおり、ylabel の近くに作成された datatips は ylabel テキストの下部になりますが、望ましい効果は逆です: datatips は軸 label の上にあります

以下で入手できる次の(それほど最小限ではない)コードでプロットを生成しました。でコメントされた行を削除する% may be removedか、ループの代わりに -78 にデータヒントを配置して、テスト スクリプトを高速化することもできますが、カスタム データヒントを作成する必要がある場合は、このコードを残します (この場合、http://undocumentedmatlab.com/blog/controlling-plot-data-tips/も参照することを検討してください):

gradientStep = 1e-1;

x=-100:gradientStep:100; xSize=numel(x);
y=x.^3-x.^2;

figH=figure(42);
lineH=plot(x,y);

ylabel('YLabel (YUnits)','FontSize',16)
xlabel('XLabel (XUnits)','FontSize',16)

dcH=datacursormode(figH);

nTips = 20; % May change the loop for a datatip at x=-78.

for pos = round(linspace(2,xSize,nTips))
  datatipH=dcH.createDatatip(lineH,...
    struct('Position',[x(pos) y(pos)]));

  orientation = 'top-left';

  if pos>1
    tipText{1} = 'The grandient here is: ';
    tipText{2} = ['\Deltax:',sprintf('%d',x(pos)-x(pos-1)),' XUnits'];
    tipText{3} = ['\Deltay:',sprintf('%d',y(pos)-y(pos-1)),' YUnits'];
  else
    tipText = 'Cannot calculate gradient here.';
  end

  bkgColor = [1 1 .5]; % May be removed.
  fontSize = 12; % May be removed.

  set(datatipH,'StringFcn',(@(~,~) tipText),'Orientation',...
    orientation,'backGroundColor',bkgColor,'FontSize',...
    fontSize,'Draggable','on');            % Only set text and orientation needed.    
  datatipTextBoxH=get(datatipH,'TextBoxHandle');  % May be removed.

  uistack(datatipH,'top'); % Unfortunately makes no effect, since the ylabel handles is not at the axes children list

  datatipTextBoxH=get(datatipH,'TextBoxHandle');
  set(datatipTextBoxH,'HorizontalAlignment','left',...
    'VerticalAlignment','top','Margin',0.02,'Interpreter',...
    'tex','FontName','Courier','FontSize',fontSize); % May be removed.

end
uistack(get(gca,'YLabel'),'bottom') % Also makes no effect, for the same reason.

私が試してみました:

  • すべてのデータヒントを上に uistack し、
  • ラベルを下に uistack します (ylabel ハンドルが軸の子ハンドルにないため、どちらも機能しません)。

更新: @horchler のソリューションを実装した後、新しい問題が発生しました。軸をズームおよびパンすると、軸ラベルも移動します。そのための小さな修正を見つけました。次の側面を変更しました。

  • データチップの z 値を 1 に設定して、常に ylabel 軸の z よりも高くなるようにします。
  • 後で ylabel を再作成すると、パンまたはズームの動きが発生します。このlocalAxisUpdateために、古い ylabel プロパティを取得し、それを新しいものに置き換え、ylabel の位置以外のすべての設定可能なプロパティをリセットする関数を実装しました。このために、このリファレンスを使用しました

結果のコードは次のとおりです。

function test
  gradientStep = 1e-1;

  x=-100:gradientStep:100; xSize=numel(x);
  y=x.^3-x.^2;

  figH=figure(42);
  lineH=plot(x,y);

  ylabel('YLabel (YUnits)','FontSize',16)
  xlabel('XLabel (XUnits)','FontSize',16)

  dcH=datacursormode(figH);

  %nTips = 20;

  %for pos = round(linspace(2,xSize,nTips))
    pos = find(x>-78,1);
    datatipH=dcH.createDatatip(lineH,...
      struct('Position',[x(pos) y(pos) 1]));

    orientation = 'top-left';

    if pos>1
      tipText{1} = 'The grandient here is: ';
      tipText{2} = ['\Deltax:',sprintf('%d',x(pos)-x(pos-1)),' XUnits'];
      tipText{3} = ['\Deltay:',sprintf('%d',y(pos)-y(pos-1)),' YUnits'];
    else
      tipText = 'Cannot calculate gradient here.';
    end

    bkgColor = [1 1 .5]; % Light Yellow
    fontSize = 12;

    set(datatipH,'StringFcn',(@(~,~) tipText),'Orientation',...
      orientation,'backGroundColor',bkgColor,'FontSize',...
      fontSize,'Draggable','on');
    datatipTextBoxH=get(datatipH,'TextBoxHandle');

    datatipTextBoxH=get(datatipH,'TextBoxHandle');
    set(datatipTextBoxH,'HorizontalAlignment','left',...
      'VerticalAlignment','top','Margin',0.02,'Interpreter',...
  %end

  % Set changes due to zoom and pan to also use adaptativeDateTicks:         
  set(zoom(figH),'ActionPostCallback',...
    @(~,~) localAxisUpdate(gca));
  set(pan(figH),'ActionPostCallback',...
    @(~,~) localAxisUpdate(gca));

end

function localAxisUpdate(aH)    
  % Fix axis label on top of datatip:
  ylh = get(aH,'YLabel');
  % Get original YLabel properties
  ylstruct = get(ylh);
  % Get settable fields:
  yfieldnames=fieldnames(rmfield(set(ylh),'Position'))';
  % Remove old label:
  delete(ylh)
  % Create new one:
  ylh = ylabel(aH,'Dummy');
  % Send it bottom:
  ylpos = get(ylh,'Position');
  set(ylh, 'Position', [ylpos(1:2) 0]);
  % Reset new ylabel to old values:
  for field=yfieldnames
    field = field{1};
    set(ylh,field,ylstruct.(field));
  end
end

このアプローチは、マウス ボタンが離されるまで ylabel が Figure を横切って移動するという望ましくない効果を生み出します。この不要な効果を削除するにはどうすればよいですか?

軸の目盛りを更新するための文書化されていない matlab ソリューションで行われたように、解決策は多かれ少なかれあると思いますが、今では ylabel postset プロパティのリスナーが必要になります。誰もそれを行う方法を知っていますか? あなたがWindowsユーザーである場合は、手助けを試みることもできます.Figureに変更(パン、ズームなど)を行った後、ylabelの位置をリセットするだけで済みます。

4

2 に答える 2

5

ハンドルを介してyラベルのz位置を明示的に設定するのはどうですか? あなたのループの後にこれを置くと、R2012bで動作するようです:

ylh = get(gca,'Ylabel')
ylpos = get(ylh,'Position');
set(ylh,'Position',[ylpos(1:2) 0]);

z 位置を調整すると、y ラベルがポップアップし、データヒント間でインターリーブすることさえできます。これがバグなのか機能なのかは完全にはわかりませんが、要素の位置をわずかに調整して、Matlab に再計算させて図を再描画させることを含む、レンダリングの問題に対する回避策がある場合があります。

于 2013-07-15T18:33:40.307 に答える