假设我在某些时候有位置坐标。假设数据看起来像
data = A[rand(100, 3), sort(rand(100, 1))]
其中data(:,1)
是x坐标,data(:,2)
是y坐标,data(:,3)
是高度,data(:,4)
是录制时间。
我可以使用
轻松绘制数据pxy = subplot(2,2,1) % Plot for X-Y-Data
plot(data(:,1), data(:,2))
ptx = subplot(2,2,2) % Plot for T-X-Data
plot(data(:,4), data(:,1))
pty = subplot(2,2,3) % ... and so on
plot(data(:,4), data(:,2))
pth = subplot(2,2,4)
plot(data(:,4), data(:,3))
现在,为了查看数字,同步轴会很棒。
一个简单的方法可能是使用linkaxes
作为时间轴,如
linkaxes([ptx, pty, pth], 'x')
然而,这使得xy-plot保持不变。因此,较弱的问题是如何将ptx
的y轴链接到pxy
的x轴。
但是让我们变得更加复杂:
假设我只有两个图,pxy
和pth
。现在,每当我缩放或平移pxy
时,pxy
中可见的时间段被提取并且pth
相应地进行了修改,那就太棒了。同样,缩放pth
会改变pxy
,只会显示正确时间范围内的数据。
这种方法应该是可扩展的,我可以绘制4个可能图的任意子集,并相应地完成链接。
知道怎么做到这一点吗?
最佳解决方案仍允许通过使用hold on
添加更多数据来修改基础图。
答案 0 :(得分:2)
你想要的(理论)问题是pxy应该是可逆的,并且在离散域(matlab是离散的)中,这变得更加清晰。
假设在pxy中有两个点P1 =(x1,y1)和P2 =(x2,y2)彼此接近;如果P1和P2在pxy中都可见,那么pth的轴窗口是否需要pxy的轴窗口? Pth1还是Pth2?您必须为此定义一些决策规则..可能基于您实际点击的两个(P1或P2)中的哪一个。
实际上,当用户在pxy上更改缩放时,您必须运行函数来更改轴,这可以按照此处的说明完成:http://www.mathworks.com/matlabcentral/answers/21627-triggering-changes-in-plot-with-zoom-function
答案 1 :(得分:1)
由于Gunthers暗示我能够自己解决问题。 由于Gunthers的回答仍然需要相当多的研究,我在下面提供了我自己的解决方案,以防万一有人在某个时候会遇到类似的问题。
首先,我在轴对象中添加了UserData所需的大部分数据。我的绘图功能(仅适用于两个图)看起来大致如下:
sb1 = subplot(1, 2, 1);
plot(data(:,1), data(:,2));
axis equal;
sb2 = subplot(1, 2, 2);
plot(data(:,4), data(:,3));
set(sb1, 'UserData', struct('projection', 'xy', 'data', data, 'link', [sb2]));
set(sb2, 'UserData', struct('projection', 'th', 'data', data, 'link', [sb1]));
panzoom(sb1, 'setlimits'); % Those two lines ensure that the zoom limits won't get changed
panzoom(sb2, 'setlimits'); % over time.
现在,我将处理程序设置为缩放功能:
z = zoom;
set(z, 'ActionPostCallback', @Track.synchronizePlots);
z = pan;
set(z, 'ActionPostCallback', @Track.synchronizePlots);
最后,这就是神奇发生的地方:
function synchronizePlots(obj, ax)
ax = ax.Axes;
ud = get(ax, 'UserData');
if ud.projection == 'xy'
% That is the part discussed in the comments above,
% which is, as I freely admit, not very sensible on a strict
% mathematical point of view. However, the result is good enough for my
% purpose
xrange = get(ax, 'XLim');
yrange = get(ax, 'YLim');
pointsvisible = ud.data(1,:) >= xrange(1) & ...
ud.data(1,:) <= xrange(2) & ...
ud.data(2,:) >= yrange(1) & ...
ud.data(2,:) <= yrange(2);
r = [min(ud.data(4, pointsvisible)), max(ud.data(4, pointsvisible))];
if length(r) == 0 % The trick above may fail if there is no point in the zoom region.
return % in that case we just do nothing.
end
else
r = get(ax, 'XLim'); % Straightforward
end
for a = ud.link % The function does not care about the number of figures that have to be changed.
linkud = get(a, 'UserData');
if linkud.projection == 'xy'
% Again, changing the xy-plot is that only part we have to work.
pointsintime = linkud.data(4,:) >= r(1) & ...
linkud.data(4,:) <= r(2);
xrange = [min(linkud.data(1, pointsintime)), ...
max(linkud.data(1, pointsintime))];
yrange = [min(linkud.data(2, pointsintime)), ...
max(linkud.data(2, pointsintime))];
if length(xrange) > 0
set(a, 'XLim', xrange);
set(a, 'YLim', yrange);
axis(a, 'equal');
end
else
set(a, 'XLim', r);
end
end
希望能帮助某人。