MATLAB: Как получить значения, по которым щелкают, относительно позиции фигуры, а не оси фигуры - PullRequest
0 голосов
/ 28 ноября 2018

В качестве некоторого фона я пытаюсь добавить фигуру-врезку к текущему графику.У меня есть большая часть этого сделано.Вот пример кода:

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) из ginput не соответствует (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);

1 Ответ

0 голосов
/ 13 января 2019

Я бы использовал небольшую функцию для преобразования единиц из «нормализованных» в «данные»:

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])  

В частности, вот основные изменения:

  1. Я не создаю третью фигуру, но копирую вставку в основную
  2. Сначала я делаю график вставки внутри невидимой фигуры, затем получаю позицию от пользователя и после ее копирования я также закрываю ее
  3. Я использую gca, чтобы получить ручки осей, так как он намного быстрее, чем findobj

Некоторые из этих изменений могут не соответствовать вашей ситуации, но ни одно из них не имеет решающего значениядля примера на работу.Суть ответа - функция выше.

...