Merging 4 separate subplots in 1 figure having 4 subplots - matlab

I have 4 different figures. Each figure contains 2 subplots (2 rows and 1 column)
The figures can be generated using the following code.
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
for i = 1 : 4
figure(i)
subplot(2,1,1)
bar(y)
subplot(2,1,2)
bar(y)
end
Having these 4 figures, is it possible to combine them in 1 figure?
the solution provided does not work with this other example where I create the figure using barwitherr..why?
for i = 1 : 4
figure(i)
subplot(2,1,1)
barwitherr([1 2 3 4;1 2 1 2], [5 6 7 8;1 2 3 4])
subplot(2,1,2)
barwitherr([1 2 3 4;1 2 1 2], [5 6 7 8;1 2 3 4])
end
for i = 1:4
figure(i);
ax = gca;
f = get(ax, 'children');
figure(5);
s = subplot(2, 2, i);
copyobj(f, s);
end

This may not be exactly what you want but is very extensible. You can loop through each of the original 4 figures and get handles for each of the subplots within it. Once the figure we are interested in using figure(i) is the current gcf object we can get a handle to each of the subplot elements with s = subplot(2, 1, i) providing we know the structure of the subplots and i is the subplot we are interested in.
We can then we use copyobj() and allchild() to copy over each of the subplots to a new subplot in the new figure
copyobj(allchild(h), s)
allchild() copies over all of the information in barwitherr() that is left out from the code you've copied from a previous edit of my answer to your question.
If we put all this together we can produce the full code as
for i = 1:4
figure(5);
n = i + (i - 1);
s1 = subplot(4, 2, n);
s2 = subplot(4, 2, n+1);
h = figure(i);
hs1 = subplot(2, 1, 1);
hs2 = subplot(2, 1, 2);
copyobj(allchild(hs1), s1)
copyobj(allchild(hs2), s2)
end
n = i + (i - 1); is used to replicate the original ordering. The output produced by this is

Related

Generate mesh and refine mesh of triangles

I need to find a way to mesh triangles then to refine using refine.
My vertices of my original triangles are stored inside a matrix of size nb_points * 2.
My faces are stored in a nb_faces * 3 matrix.
The data for each face is stored in a nb_face * 1 matrix.
The meshing is done by diving the area using the middles of the segments of the triangles.
Example :
Origin :
vertices = [0 1 ;
2 3 ;
4 1 ;
4 5];
faces = [1 2 3;
2 3 4];
data = [1 2];
Result expected after meshing :
vertices = [0 1;
2 3;
4 1;
4 5;
1 2;
3 2;
2 1;
3 4;
4 3];
faces = [1 5 7;
2 5 6;
5 6 7;
7 6 3;
2 6 8;
6 8 9;
6 9 3;
8 4 9];
data = [1 1 1 1 2 2 2 2];
I am displaying using :
FV.Vertices = vertices;
FV.Faces = faces;
FV.FaceVertexCData = data;
figure; hold on; axis equal; grid on;
patch(FV,'FaceColor','flat');
Precision :
I do not want to use the following functions which gives way too many vertices and faces :
generateMesh()
refinemesh()
The data are temperatures since this is a simulation of heat transfer.
With a for loop it can be done quite easily, here is one solution:
% Dummy data
vertices = [0 1 ;
2 3 ;
4 1 ;
4 5];
faces = [1 2 3;
2 3 4];
data = [1 2];
% Number of vertices
vnum = size(vertices,1);
% new faces empty vector
nfaces = [];
% triangular shift
tshift = [2,-1,-1].';
% Run the algorithm
for ii = 1:size(faces,1)
% For each triangle get the 3 pairs of vertices
nsk = [faces(ii,1), faces(ii,2);faces(ii,2), faces(ii,3);faces(ii,3), faces(ii,1)];
% Compute the center of each pair of vertices
cmiddle = (vertices(nsk(:,1),:)+vertices(nsk(:,2),:))/2
% Compute the new faces
nfaces = [nfaces;[nsk(:,1),vnum+(ii*3-3+[1:3].'),vnum+(ii*3-3+[1:3].')+tshift];[(vnum+(ii*3-2)):(vnum+(ii*3))]]
% Add the new vertices
vertices = [vertices;cmiddle];
end
% Delete the duplicate vertices
[vertices,~,ind] = unique(vertices,'rows');
faces = ind(nfaces);
% Plot
figure; hold on; axis equal; grid on;
patch('Faces',faces,'Vertices',vertices,'FaceVertexCData',kron(data,ones(1,4)).','FaceColor','flat')
colorbar
If you find a way to generate the nsk vector without for loop you could even get rid of the loop. This code will only work on triangle, but it can be adapted if needed.
Result:
You can repeat the operation:

How to shade area and make it transparent between two lines in MATLAB?

I shaded the area between two lines, it's not very clean:
area(xData,[Y1(:) ,Y2(:)-Y1(:)]); hold on
colormap([1 1 1; 0 0 1]);
How to make it transparent too in MATLAB? So that it comes like:
ref:peltiertech.com
You can use the FaceAlpha property of the area object to set the transparency level:
xData = 1:7;
Y1 = [3 2 1 4 3 2 1];
Y2 = [8 6 9 8 7 5 6];
area(xData, Y2, 'EdgeColor',[0 .447 .741], 'FaceColor',[0.929 .694 .125], 'FaceAlpha',.3);
hold on
area(xData, Y1, 'EdgeColor',[0 .447 .741], 'FaceColor', [1 1 1]);
A cleaner approach is to use patch instead of area:
h = patch([xData xData(end:-1:1) xData(1)], [Y1 Y2(end:-1:1) Y1(1)], 'b');
set(h, 'EdgeColor',[0 .447 .741], 'FaceColor',[0.929 .694 .125], 'FaceAlpha',.3)

Plot data ignoring some X-axis values on Matlab

I'm trying to plot some data on Matlab using the following code:
x = [1 2 5 6 7 9]
y1 = [1 2 3 2 1 2]
y2 = [2 2 2 1 3 3]
y3 = [1 1 2 3 1 1]
plot(x,y1,'--.','markersize',20); hold on;
plot(x,y2,'--.','markersize',20); hold on;
plot(x,y3,'--.','markersize',20); hold off;
legend('y1','y2','y3');
xlim([1 9]);
ylim([0 4]);
And I'm getting the following result:
Note that I have no Y values for the X positions 3, 4 and 8, but the X axis is still showing these X values in the graph.
There is some way that I can ignore the positions 3, 4 and 8 in the X-axis, and show only the Y values for the X positions 1, 2, 5, 6, 7 and 9?
I can use the following command to 'hide' these positions:
set(gca, 'XTick', x);
But the gaps related to these positions are still there.
Update:
This is the graph I'm trying to create (it was created on paint):
Note: in my case, the X-axis just represents the IDs of some images, and because of that I just need to show the numbers.
You can get the plot you want by first leaving x out in the calls to plot (so it plots against the array index) then altering the XTick and XTickLabel properties of the axes (and adjusting the x limit slightly):
plot(y1,'--.','markersize',20); hold on;
plot(y2,'--.','markersize',20);
plot(y3,'--.','markersize',20);
legend('y1','y2','y3');
xlim([1 numel(x)]); % Note numel is used here
ylim([0 4]);
set(gca, 'XTick', 1:numel(x), 'XTickLabel', cellstr(num2str(x(:))));
I am not sure if you need gaps between plot lines. If you wish no values to be plotted there, try replacing the values by nan. For example,
x = [1 2 3 4 5 6 7 8 9]
y1 = [1 2 nan nan 3 2 1 nan 2]
y2 = [2 2 nan nan 2 1 3 nan 3]
y3 = [1 1 nan nan 2 3 1 nan 1]
plot(x,y1,'--.','markersize',20); hold on;
plot(x,y2,'--.','markersize',20); hold on;
plot(x,y3,'--.','markersize',20); hold off;
legend('y1','y2','y3');
xlim([1 9]);
ylim([0 4]);
This will give a plot like this:
Sounds like you need stem.
stem(x, y1);
legend('y1');

Evaluating MATLAB Quadratic rBform

I have created a planar piecewise biarc curve in MATLAB using the rscvn function. I have been able to plot it as follows:
p = [0 1 2 3; 2 6 3 9];
B = rscvn(p)
fnplt(B)
hold on
scatter([0 1 2 3],[2 6 3 9]);
hold off
Unfortunately I can't for the life of me figure out how to evaluate the function B for an arbitrary position, say 2.6.
How should I attempt this in MATLAB?
You can evaluate a function from the curve fitting toolbox using the fnval function.
See https://www.mathworks.com/help/curvefit/fnval.html
Example code
p = [0 1 2 3; 2 6 3 9];
B = rscvn(p);
fnval(B,2.6)
Output
ans =
1.8526
5.1884
Edit From your comment and the format of your data I assume you are actually looking to estimate a continuous function from your data. In that case you can use.
p = [0 1 2 3; 2 6 3 9];
C = csapi(p(1,:), p(2,:));
fnplt(C)
hold on
scatter([0 1 2 3],[2 6 3 9]);
hold off
fnval(C,2.6)
Output
ans =
4.4960

In matlab, plot a heatmap and a line plot on the same figure

In matlab 2014b, I want to make a heatmap and then overlay a line plot using the right y-axis. For example
colormap bone
data = rand(6);
imagesc(data)
ax = gca;
ax.XTick = [1 2 3 4 5 6];
ax.YTick = [1 2 3 4 5 6];
hold on
Now plot a line but use the right y-axis because this has negative values:
x2 = [1 2 3 4 5 6];
y2 = [-0.0001 -0.0997 -0.1997 -0.2995 -0.3994 -0.4995];
plot(x2,y2,'r')
You can make it with a variation of plotyy where the first plot is composed of NaNs.
Here is the code:
hold on
colormap bone
data = rand(6);
imagesc(data)
ax = gca;
yT = ax.YTick;
x2 = [1 2 3 4 5 6];
y2 = [-0.0001 -0.0997 -0.1997 -0.2995 -0.3994 -0.4995];
[ax, ~, h] = plotyy(yT*NaN, yT, x2,y2);
ax(1).YLim = [yT(1)-0.5 yT(end)+0.5];
ax(1).YTick = yT;
ax(1).YColor = [0 0 0];
set(h, 'Color', 'r');
ax(2).YColor = [1 0 0];
ax(2).YTick = -0.5:0.1:0;
and the result:
Best,