Getting the value on plot curve with click and evaluate with the value (プロットしたグラフ​上の値をクリックして​得て、その値を計算に​使いたい)

I would like to perform the following tasks. I would be happy to learn how to do that.
---- Create a graph with mlx file. (Plot)
Ia_start = 1
Ia_incre = 1
Ia_end = 3
figure
ax = gca;.
set(gcf, 'visible', 'on','Position',[400 50 1000 940])
hold on
for Ia = Ia_start : Ia_incre : Ia_end
fimplicit(@(id,iq) id.^2+iq.^2 - Ia.^2);
end
hold off
---- Click on a point on the graph plotted here to obtain its value.(for example)
x=0.672258
y=1.8836
 
---- For example, we want to compute and get the answer = x + y.

 Accepted Answer

figureのコールバックを設定することにより、カーソル位置が取得可能です。
また、必要であれば datatip を利用することで、関数上のデータを取得することもできます。
By setting up a callback for the figure, it becomes possible to obtain the cursor's position.
Additionally, if needed, you can also retrieve data from the function using a "datatip".
function test
Ia_start = 1;
Ia_incre = 1;
Ia_end = 3;
figure
ax = gca;
set(gcf, 'visible', 'on','Position',[400 50 1000 940])
hold on
for Ia = Ia_start : Ia_incre : Ia_end
fp(Ia) = fimplicit(@(id,iq) id.^2+iq.^2 - Ia.^2);
% append new data tip if necessary
row = dataTipTextRow("X + Y", @(x,y)(x+y));
fp(Ia).DataTipTemplate.DataTipRows(end+1) = row;
end
hold off
f = gcf;
ax.Units = "normalized";
axWidth = f.Position(3) * ax.Position(3);
axHeight = f.Position(4) * ax.Position(4);
axSX = f.Position(3) * ax.Position(1);
axSY = f.Position(4) * ax.Position(2);
axXmin = ax.XLim(1);
axXmax = ax.XLim(2);
axYmin = ax.YLim(1);
axYmax = ax.YLim(2);
f.WindowButtonDownFcn = @getaxPos;
% mouse callback
function pos = getaxPos(src,~)
last_seltype = src.SelectionType;
C = get (gcf, 'CurrentPoint');
x = (C(1) - axSX) / axWidth * (axXmax - axXmin) + axXmin;
y = (C(2) - axSY) / axHeight * (axYmax - axYmin) + axYmin;
pos = [x, y];
if strcmp(last_seltype,'normal') % left click
% find data on the fimplicit function using "datatip"
for Ia = Ia_start : Ia_incre : Ia_end
dt(Ia) = datatip(fp(Ia),x,y);
dist(Ia) = norm([x,y] - [dt(Ia).X, dt(Ia).Y]);
end
[~,idx] = min(dist); % find nearest data from 3 fimplicits
for Ia = Ia_start : Ia_incre : Ia_end
if Ia==idx
dt(Ia).Visible = 'on';
z = dt(Ia).X + dt(Ia).Y % disp z to command window
else
dt(Ia).Visible = 'off'; % turn off other datatips
end
end
end
end
% set (f, 'WindowButtonDownFcn', '');
end

7 Comments

早々のご教示をありがとうございました。
私のやりたいことはこれでできそうです。
重ねて、御礼申し上げます。
Thank you for your prompt guidance.
I think this will do what I want to do.
Again, thank you very much.
fimplicit にコールバック設定すれば、座標変換やどのラインをクリックしたかの判定は不要でした
かなりシンプルになるので追加で
ついでに、arrayfun でまとめて描いてみました
前の書き方でも、それ以外は同じで動くはずです
ただなぜか、fimplicit の datatip は、各ラインの初回クリックでは表示されない(2回目にまとめて表示され、それ以降は表示される)ようなので、テキスト表示にしてみました
figure(Visible="on");
r_values = 1:3;
axis equal
hold on;
fp = arrayfun(@(r) fimplicit(@(x,y) x.^2 + y.^2 - r.^2, [-r r -r r]), r_values);
hold off;
for Ia=r_values
set(fp(Ia), 'ButtonDownFcn',@(src, event) lineCallback(src,event))
% append new data tip if necessary
row = dataTipTextRow("X + Y", @(x,y)(x+y));
fp(Ia).DataTipTemplate.DataTipRows(end+1) = row;
end
function lineCallback(src,event)
if event.Button == 1 % left click
C = get (gca, 'CurrentPoint');
x = C(1, 1); y = C(1, 2);
dt = datatip(src,x,y);
dataX = dt.X; dataY = dt.Y;
z = dataX + dataY
% if no need datatip display
dt.Visible = "off";
hold on
plot(dataX,dataY,'x',MarkerSize=4, MarkerEdgeColor="black" )
hold off
text(dataX+0.1, dataY, "z = " + num2str(z));
end
end
返答が遅れてしまい、申し訳ありません。
非常にわかりやすく助かりました。
こちらを採用させていただきます。
ありがとうございました。
以前におしえていただきました内容を用いて、アプリケーションデザイナーへの移植をおこなっています。
しかし、次のエラーを出して動作しません。どうしても分からないので、ご教示を願えないでしょうか?
【エラー】
関数 'lineCallback' の入力または出力の数または型が正しくありません。
エラー: test>@(app,event)lineCallback(app,event) (行 46)
set(fp(Ia), 'ButtonDownFcn',@(app,event) lineCallback(app,event))
ImplicitFunctionLine ButtonDownFcn の実行中にエラーが発生しました。
【ボタンのコールバックとして次の通り変更したものを配置】
% Button pushed function: Button
function ButtonPushed(app, event)
r_values = 1:3
% app.UIAxes = equal;
hold(app.UIAxes,'on');
fp = arrayfun(@(r) fimplicit(app.UIAxes, @(x,y) x.^2 + y.^2 - r.^2, [-r r -r r]), r_values)
hold(app.UIAxes,'off');
for Ia=r_values
set(fp(Ia), 'ButtonDownFcn',@(app,event) lineCallback(app,event))
% append new data tip if necessary
row = dataTipTextRow("X + Y", @(x,y)(x+y));
fp(Ia).DataTipTemplate.DataTipRows(end+1) = row;
end
end
【関数→プライベート関数 の場所に次の通り変更したものを配置】
methods (Access = private)
function lineCallback(app,event)
if event.Button == 1 % left click
C = get (app.UIAxes, 'CurrentPoint');
x = C(1, 1); y = C(1, 2);
dt = datatip(app,x,y);
dataX = dt.X; dataY = dt.Y;
z = dataX + dataY;
% if no need datatip display
dt.Visible = "off";
hold(app.UIAxes,'on');
plot(dataX,dataY,'x',MarkerSize=4, MarkerEdgeColor="black" )
hold(app.UIAxes,'off');
text(dataX+0.1, dataY, "z = " + num2str(z));
end
end
end
dattip を使わない簡単な例を添付します。
methods (Access = private)
function lineCallback(app, ~, event)
% クリックされた座標を取得
C = get(app.UIAxes, 'CurrentPoint');
x = C(1, 1);
y = C(1, 2);
% クリックされた座標を使用して必要な処理を実行
if event.Button == 1 % 左クリック
z = x + y;
% データポイントを描画
hold(app.UIAxes, 'on');
plot(app.UIAxes, x, y, 'x', 'MarkerSize', 4, 'MarkerEdgeColor', 'black');
hold(app.UIAxes, 'off');
text(app.UIAxes, x + 0.1, y, "z = " + num2str(z));
end
end
end
% Callbacks that handle component events
methods (Access = private)
% Button pushed function: Button
function ButtonPushed(app, event)
cla(app.UIAxes)
r_values = 1:3;
axis(app.UIAxes, 'equal');
hold(app.UIAxes, 'on');
fp = arrayfun(@(r) fimplicit(app.UIAxes, @(x,y) x.^2 + y.^2 - r.^2, [-r r -r r]), r_values);
hold(app.UIAxes, 'off');
for Ia = r_values
set(fp(Ia), 'ButtonDownFcn', @(src, event) lineCallback(app, src, event));
end
end
end
今回も詳細にご教示いただき、ありがとうございました。大変よくわかりました。特に、propertiesでコールバックさせる場合の引数が(app, src, event)であることをおしえていただき、助かりました。

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!