Combining Two Plots into One Won't Work!
4 views (last 30 days)
Show older comments
Hello dear experts,
I am trying to combine two figures into one, and I am using the solution already provided here, however, it is not working for me! I really appreciate it if you help me with that. Here I attached two figures as an exmaple.
This is the code that I am using:
fh1 = open('f1.fig');
fh2 = open('f2.fig');
ax1 = get(fh1, 'Children');
ax2 = get(fh2, 'Children');
ax2p = get(ax2(1),'Children');
copyobj(ax2p, ax1(1));
0 Comments
Accepted Answer
Star Strider
on 23 Jan 2021
Not trivial, however also not difficult.
F{1} = openfig('f1.fig');
F{2} = openfig('f2.fig');
figure
hold on
for k1 = 1:numel(F)
Ax = F{k1}.CurrentAxes;
lines = findobj(Ax, 'Type','Line');
sktrs = findobj(Ax, 'Type','scatter');
for k2 = 1:numel(lines)
xl{k2} = lines(k2).XData; % Force Row Vector
yl{k2} = lines(k2).YData; % Force Row Vector
xs{k2} = sktrs(k2).XData; % Force Row Vector
ys{k2} = sktrs(k2).YData; % Force Row Vector
end
xvl = cell2mat(xl); % Extract From Cell Array
yvl = cell2mat(yl); % Extract From Cell Array
xvs = cell2mat(xs); % Extract From Cell Array
yvs = cell2mat(ys); % Extract From Cell Array
p(k1) = plot(xvl, yvl, 'DisplayName',sprintf('Fig(%d) Line',k1), 'LineWidth',1);
s(k1) = scatter(xvs, yvs, 'p', 'DisplayName',sprintf('Fig(%d) Scatter',k1));
end
hold off
grid
title(Ax.Title.String)
xlabel(Ax.XLabel.String)
ylabel(Ax.YLabel.String)
legend('Location','SE')
.
2 Comments
Star Strider
on 24 Jan 2021
As always, my pleasure!
To understand my code, it is necessary to understand the details of Graphics Objects. It is a bit difficult to explain everything in detail (there is too much to explain), however there are a number of functions and structure references that make it possible to find the necessary information relatively easily.
The ‘Ax’ assignment builds on the information available by examining the handles that constitute the elements of figure ‘F’, and my experience working with them (knowing that the lines are part of the Axes object). The findobj call is a shortcut to the equivalent:
Kids = Ax.Children;
lines = Kids(1);
sktrs = Kids(2);
that I would otherwise have used so I would not have to search for them.
Using:
Kids = Ax.Children;
reveals all of them. The rest is just calling them appropriately to get the data.
The ‘k2’ loop retrieves the information from the Axes object Children object. Again, this just involved addressing them.
The plot calls are within the hold function so that they are all plotted on the same destination axes created by the initial figure call before the loop.
The 'DisplayName' arguments are described in the legend documentation section Specify Legend Labels During Plotting Commands.
The title and axis label calls use the existing values, and again address the figure structure fields from the input figures. They are the same in both figures, otherwise I would have referred to them, however not included them in the destination figure.
All of this is colloquially termed ‘handle diving’ or ‘handle spelunking’. It just takes experience with the figure handle structures to know where to look.
Note — My code as written works here because there are equal numbers of line and scatter objects in the original figures. If there were more of them, or different numbers or types of objects (i.e. surface, bar or others), the code would need to be changed to accommodate those. It would not automatically detect or count them.
.
More Answers (1)
snr matlb
on 23 Jan 2021
I guess that you can use "hold on" if you can draw the plot again. "hold on" holds the first plot while it is drawing the other one. If the axes are common, I think that you can use it.
See Also
Categories
Find more on Specifying Target for Graphics Output in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!