MATLABでプロットなどする時に、PC環境つまりモニター・ディスプレイの構成によってFigureの位置が異なってしまうことがある。
MATLABにはモニターの位置を取得することができるので、それを活用するとある程度はFigureの位置を制御できる。
最近、xrdp経由でLinuxのデスクトップ環境を使っているが、この場合素のWindowsで使う場合とモニター座標が異なるらしい。
例えばWindowsで
moniInfo = groot;
とすると以下のようになる。
この場合モニター・ディスプレイは物理的に二つあって、MoniterPositionがそれを反映している。
>> moniInfo
moniInfo =
Graphics Root のプロパティ:
CurrentFigure: [1×1 Figure]
ScreenPixelsPerInch: 96
ScreenSize: [1 1 1920 1080]
MonitorPositions: [2×4 double]
Units: 'pixels'
ところが、xrdp経由のLinux上のMATLABでは
>> moniInfo
moniInfo =
Graphics Root のプロパティ:
CurrentFigure: [1×1 Figure]
ScreenPixelsPerInch: 80
ScreenSize: [1 1 3200 900]
MonitorPositions: [1 1 3200 900]
Units: 'pixels'
となる。
素のWindowsと異なるのが、ScreenPixelPerInch、ScreenSize, MoniterPositons の三つある。
スクリーン・サイズが異なるのはScreenPixelPerInchが80になっているためだろう。 たとえばScreenSizeが3200×900になっているが、これをScreenPixelPerInchを96相当に変換するなら、3840×1080となる。 3840は1920の2倍なので、pixel数は正しい。
ただし、MonitorPositionsは横幅が大きい一枚のモニター・ディスプレイとして認識されているようだ。 これはxrdpの仕様上しかたのないと推測される (物理的なモニター・サイズを授受しない仕様なのだと思われる)。 (NativeなLinux上で動かす場合は、おそらく物理的なモニターサイズを取得できるので、素のWindows上と同様の結果を返すのではないか。←あくまで推測。)
以上のことから、xrdp経由でもそれっぽい位置にfigureを配置させる場合は以下のようなコードになる。
下の例ではx, y座標はfigure全体が一つのモニターの中央になるように計算している。 また、モニターが複数あっても grootで取得された1番目のモニターに配置する。
figh_101 = figure(101);
x = 0:1e-2:2*pi;
y = sin(x);
plot(x, y)
moniInfo = groot;
fig_W = 800 * moniInfo.ScreenPixelsPerInch / 96; % in pixels
fig_H = 600 * moniInfo.ScreenPixelsPerInch / 96;
if size(moniInfo.MonitorPositions, 1) < 2 % display 数が1つの場合(xrdp経由の場合など)
if moniInfo.MonitorPositions(1,3) * 92 / moniInfo.ScreenPixelsPerInch > 2000
% monitor 横幅が2000 pixelより大きい場合は半分にする
moniterRight = moniInfo.MonitorPositions(1,3) / 2;
end
else
moniterRight = moniInfo.MonitorPositions(1,3) ;
end
moniterLeft = moniInfo.MonitorPositions(1,1);
moniterTop = moniInfo.MonitorPositions(1,4);
moniterBottom = moniInfo.MonitorPositions(1,2);
fig_X = moniterLeft + (moniterRight - fig_W) / 2;
fig_Y = moniterBottom + (moniterTop - fig_H) / 2;
figh_101.Position = [fig_X, fig_Y, fig_W, fig_H];