matlab - MATLAB:如何获取相对于图形位置而不是图形轴的点击值
问题描述
作为一些背景,我想做的是在当前情节中添加一个插图。我已经完成了大部分工作。这是一个代码示例:
h = figure(1); %Arbitrary figure #1
plot(990000:1000000,990000:1000000,'--r');
g = figure(2); %Arbitary figure #2
plot(randn(100,1),randn(100,1),'.k');
figure(3); %Figure to combine the above two figures
new_fig=gcf;
main_fig = findobj(h,'Type','axes');
h_main = copyobj(main_fig,new_fig);
set(h_main,'Position',get(main_fig,'Position'))
inset_fig = findobj(g,'Type','axes');
h_inset = copyobj(inset_fig,new_fig);
ax=get(main_fig,'Position');
inset_size = 0.3;
X = 0.2; %Left position of inset hard-coded in
Y = 0.6; %Bottom position of inset hard-coded in
set(h_inset,'Position', [X Y inset_size inset_size])
close(h); close(g);
在上面的代码示例中,我只是手动将插图的 X 和 Y 位置设置为 X = 0.2 和 Y = 0.6。
但是,我坚持的棘手部分是我希望 X 和 Y 位置由用户确定。我希望用户能够在某处单击该图,并且该单击点成为插图的中心点。
不幸的是,ginput 并没有按照我想要的方式工作,因为 [x,y] = ginput(1) 返回相对于图形轴的值 x 和 y。这是一个代码示例:
h = figure(1); %Arbitrary figure #1
plot(990000:1000000,990000:1000000,'--r');
[x,y] = ginput(1);
正如您在此处看到的,x 和 y 大约为 10^5,因为它们以绘图轴为参考。所以 (x,y) fromginput
不匹配用于设置图形位置的 (X,Y)。
任何想法如何将 (x,y) 转换为 (X,Y)?
编辑:我尝试进行以下缩放,它“几乎”有效,但不太有效,任何关于如何改进的想法都值得赞赏:
h = figure(1); %Arbitrary figure #1
plot(990000:1000000,990000:1000000,'--r');
[x,y] = ginput(1);
limx = xlim;
limy = ylim;
g = figure(2); %Arbitary figure #2
plot(randn(100,1),randn(100,1),'.k');
figure(3); %Figure to combine the above two figures
new_fig=gcf;
main_fig = findobj(h,'Type','axes');
h_main = copyobj(main_fig,new_fig);
set(h_main,'Position',get(main_fig,'Position'))
inset_fig = findobj(g,'Type','axes');
h_inset = copyobj(inset_fig,new_fig);
ax=get(main_fig,'Position');
inset_size = 0.3;
% X = 0.2; %Left position of inset hard-coded in
% Y = 0.6; %Bottom position of inset hard-coded in
%CONVERT ginput (x,y) to axis position (X,Y)
X = (x-min(limx))/diff(limx)*ax(3);
Y = (y-min(limy))/diff(limy)*ax(4);
set(h_inset,'Position', [X Y inset_size inset_size])
close(h); close(g);
解决方案
我会使用一个小函数将单位从“标准化”转换为“数据”:
ax2norm = @(x,y,ax) [...
ax.Position(3)*((x-ax.XLim(1))./range(ax.XLim))+ ax.Position(1)...
ax.Position(4)*((y-ax.YLim(1))./range(ax.YLim))+ ax.Position(2)];
% white area * ((value - axis min) / axis length) + gray area
其中x
和y
是归一化坐标,ax
是要转换为其数据单位的坐标区句柄。
下面的示例与您想要实现的类似,但更简洁和通用:
% create the inset:
insetFig = figure('Visible','off');
plot(randn(100,2),'.k')
temp_ax = gca;
% create the main figure:
mainFig = figure;
plot(1:10,1:10,'--r')
main_ax = gca;
% get position for inset:
inset_size = 0.3;
[x,y] = ginput(1);
XY = ax2norm(x,y,main_ax);
% copy the inset to the position:
inset_ax = copyobj(temp_ax,mainFig);
close(insetFig);
set(inset_ax,'Position', [XY-inset_size/2 inset_size inset_size])
特别是,以下是主要变化:
- 我不创建第三个图形,而是将插图复制到主要图形中
- 我首先在一个不可见的图形中制作插图,然后从用户那里获取位置,复制后我也关闭它
- 我
gca
用来获取轴手柄,因为它比findobj
其中一些更改可能不适合您的情况,但它们都不是示例工作的关键。答案的本质是上面的函数。
推荐阅读
- javascript - 将一个很长的字符串作为参数发送到 asmx Web 服务
- flutter - Flutter:每次访问页面时如何在底部导航栏上重新加载页面
- spring-security - 使用 Spring Security 在同一应用程序中基于 SAML2 和基于表单的登录
- node.js - 无法使用 npm start 命令启动反应应用程序
- loops - 了解 Eiffel 循环变体/不变量
- reactjs - React Redux 不在表中显示数据
- python - 遍历数组从数组中读取 n-1 个元素
- java - 如何从一堆 JAR 文件创建一个 Maven 兼容存储库?
- python - 如何在 Windows 上的 Python 3.9 上安装 psycopg2?
- flutter - NoSuchMethodError:在 null 上调用了 getter 'name'