Hojo.Timberwolf
Hojo.Timberwolf

Reputation: 1091

duplicate axes in a figure

Sorry for a somewhat simple question. I am trying to generate a figure which displays the same animation but in different subplots. I'm starting simple and primarily focusing on duplicating the plot first.

I was originally thinking of attaching the handle for the subplot to the other plots

afig = figure;
a1{1} = axes('Position',[.01,.2,.2,.2], 'color','none','Xlim',[-10,10],'Ylim',[-10,10]);
a1{2} = a1{1};
a1{2}.Position = [.3,.2,.2,.2];
a1{3} = a1{1};
a1{3}.Position = [.6,.2,.2,.2];

obj = patch('Parent',a1{1},'XData',[1,3,1],'YData',[1,1,3]);

enter image description here

But this just moves the existing plot around as opposed to duplicating it. (on account that I'm still referring to the same object even though it has different names)

I next thought of just recreating the same setup 3 times and then update the animation, looping through the three, but this feels inefficient and computationally intensive.

afig = figure;
a1{1} = axes('Position',[.01,.2,.2,.2], 'color','none','Xlim',[-10,10],'Ylim',[-10,10]);
a1{2} = axes('Position',[.3,.2,.2,.2], 'color','none','Xlim',[-10,10],'Ylim',[-10,10]);
a1{3} = axes('Position',[.6,.2,.2,.2], 'color','none','Xlim',[-10,10],'Ylim',[-10,10]);

obj{1} = patch('Parent',a1{1},'XData',[1,3,1],'YData',[1,1,3]);
obj{2} = patch('Parent',a1{2},'XData',[1,3,1],'YData',[1,1,3]);
obj{3} = patch('Parent',a1{3},'XData',[1,3,1],'YData',[1,1,3]);

enter image description here

Is there a way to call 1 subplot, update that 1 subplot but have it propagate to other subplots?

Upvotes: 1

Views: 1315

Answers (1)

zeeMonkeez
zeeMonkeez

Reputation: 5157

It really depends on what you want to do in the end, how complex the animations are, and if you can prepare your plots in advance.

First, if there are only a few objects, you could use the linkprop function to link graphics objects' properties:

afig = figure;
a1{1} = axes('Position',[.01,.2,.2,.2], 'color','none','Xlim',[-10,10],'Ylim',[-10,10]);
obj = patch('Parent',a1{1},'XData',[1,3,1],'YData',[1,1,3]);

a1{2} = copyobj(a1{1}, afig);
a1{2}.Position = [.3,.2,.2,.2];

a1{3} = copyobj(a1{1}, afig);
a1{3}.Position = [.6,.2,.2,.2];


linked_objects = [ a1{1}.Children, a1{2}.Children,  a1{3}.Children];
property_names = {'XData', 'YData', 'ZData'};

hlink = linkprop(linked_objects, property_names);


for ii = 1:10
    obj.XData(1) = ii;
    drawnow
    pause(0.01)
end

Here, we first create the base plot, then we copy the axes (note that children objects get copied, too, but not callbacks and other properties, see copyboy). We then link properties we may want to change during the animation (note that you could also link the axes' view properties), and then change them in a loop.

Another approach would be to change the object's properties in a main axes in every loop iteration, and copy the main axes' children to the other axes afterwards. This approach may be more costly – as a lot of objects get copied and rendered – but on the other hand, individual properties do not have to be tracked. Here is an example:

afig = figure;

a1{1} = axes('Position',[.01,.2,.2,.2], 'color','none','Xlim',[-10,10],'Ylim',[-10,10]);
obj = patch('Parent',a1{1},'XData',[1,3,1],'YData',[1,1,3]);

a1{2} = copyobj(a1{1}, afig);
a1{2}.Position = [.3,.2,.2,.2];

a1{3} = copyobj(a1{1}, afig);
a1{3}.Position = [.6,.2,.2,.2];

for ii = 1:10

    obj.XData(1) = ii;

    delete(a1{2}.Children);
    delete(a1{3}.Children);
    copyobj(a1{1}.Children, a1{2});
    copyobj(a1{1}.Children, a1{3});

    drawnow
    pause(0.01)
end

Finally, it could be an option to use getframe to just capture the rendered image and display it in the copy axes.

Upvotes: 1

Related Questions