3

情况

假设我在某些时候有位置坐标。假设数据看起来像

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 图保持不变。因此,较弱的问题是如何将 的 y 轴链接ptx到 的 x 轴pxy

但让我们变得更复杂:

实际问题

假设我只有两个地块,pxy并且pth. 现在,每当我放大或平移pxy可见的时间跨度时,它会被pxy提取并pth相应地修改。类似地,缩放以一种方式pth改变pxy,即只有正确时间跨度内的数据可见。

这种方法应该是可扩展的,我可以绘制 4 个可能图的任意子集,并相应地完成链接。

知道如何做到这一点吗?

最佳解决方案仍然允许通过使用添加更多数据来修改该基础图hold on

4

2 回答 2

2

您想要的(理论上)问题是 pxy 应该是可逆的,并且在离散域(matlab 是离散的)中,这变得更加不清楚。

假设您有两个点 P1=(x1,y1) 和 P2=(x2,y2) 在 pxy 中彼此靠近;如果 P1 和 P2 在 pxy 中可见,您希望 pxy 的轴窗口对应于 pth 上的哪个轴窗口?Pth1 还是 Pth2?您必须为此定义一些决策规则。也许基于您实际单击的两个(P1 或 P2)中的哪一个。

实际上,当用户更改 pxy 上的缩放时,您必须运行函数来更改轴,这可以按照此处的说明完成:http: //www.mathworks.com/matlabcentral/answers/21627-triggering-changes-in-plot -带缩放功能

于 2012-05-04T10:21:26.023 回答
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

希望对某人有所帮助。

于 2012-05-04T16:45:54.717 回答