matlab imshow not fitting the defined axes - matlab

I have to generate a video made of three main objects coming from some data previously generated:
1)patch graph of a thickness
2)a grey-scale image
3)a plot
I generated three axes: ax1,ax2,ax3 with their properties. When I put the image inside ax2, I always get an image that is smaller, centred, and scaled.
This is what i get:
ResultNotWanted
the upper patch graph and the image should be of the same length but I'm not able to figure out how.
Part of the code:
File=dir(File2Load);
%Figure handles and figure object before the loop to reduce the
%computational power required by the loop itself.
fig=figure('visible','on'); %set off when doing the loop of the whole video
fig.Position=([0 0 900 500]);
pipeLength=371;
limY_TBS=400;
img=[];
x=(1:pipeLength);
xp=[x flip(x)];
z=[];
x1=[-1 x x(end)+1 x(end)+1 flip(x) -1];
y=ones(1,numel(x1));
y(1:end/2)=y(1:end/2)*(limY_TBS+10);
y(end/2+1:end)=-1*y(end/2+1:end);
ax1=axes(fig,'Position',[0.1 0.60 0.80 0.3]);
p1=patch(ax1,x1,y,ones(length(x1),1),'FaceColor','interp');
hc=colorbar(ax1,'Location','manual','Position',[0.91 0.6 0.02 0.3]);
title(hc,'°C');
xticks(ax1,0:50:350)
xticklabels(ax1,["0","35","70","105","140","175","210","245 [mm]"])
set(ax1,'TickDir','out')
xlim(ax1,[0 pipeLength])
yticks(ax1,0:25:limY_TBS)
yticklabels(ax1,["0","","","","100","","","","200","","","","300","","","","400"])
clim(ax1,[20 40]);
%limit of the techinique, the value will build a patch over te region that are out of interest because too thick
patchHeigth=limY_TBS; %patch heigth to be plot when thickness>limT_TBS. This will be the heigth of the patch plotted
colormap(ax1,'turbo')
p2=patch(ax1,x1,y,'w');
ylim([0 limY_TBS]);
ylabel("Film Thickness [" + char(181)+ "m]",'FontSize',15),
%set axes 2 for the image
ax2=axes(fig,'Position',[0.1 0.20 0.8 0.3]);
mfile=matfile(Vid(1).path);
mOnes=size(cell2mat(mfile.newIred(1,1)));
size(cell2mat(mfile.newIred(1,1)),2)],'YData',[-10 size(cell2mat(mfile.newIred(1,1)),1)]);
imgGraph=imshow(mOnes,'Parent', ax2,'XData',[0 size(cell2mat(mfile.newIred(1,1)),2)],...
'YData',[-10 size(cell2mat(mfile.newIred(1,1)),1)],...
initialMagnification','fit');
imgGraph.CDataMapping="direct";
t1=text(ax2,1,200,' ','FontSize',15,'FontSmoothing', 'on'); %time text
t2=text(ax2,600,200,' ','FontSize',15,'FontSmoothing', 'on'); %acceleration text
t3=text(ax2,300,200,' ','FontSize',15,'FontSmoothing', 'on'); %power text
ax3=axes(fig,'Position',[0.1 0.05 0.8 0.1]); %axis for the acceleration graph
I would like that the image on ax2 to completely fit the defined axes to have the same horizontal span of the top graph.
Thank you for any support that you can give.
Riccardo

Related

How to plot point and vectors in Matlab

A = [239920.240412166 1.31193313030682;
243577.444235102 1.38185205485119;
241899.250050298 1.51264147493485;
244659.326936560 1.50845243215867;
239862.361809342 1.50810833389632;
238395.616682194 1.37125000688350;
244558.389789124 1.27212093329482;
244290.890880318 1.35116080948488;
240303.711239396 1.36064181572699;
237464.430450140 1.48857869573721;
244415.381196104 1.51252425335623;
239855.328594799 1.29178640586301;
239304.806448742 1.31075813783171;
244827.243024016 1.32080934043223;
241465.885648910 1.53667019314427;
241139.254464482 1.40424079027764;
242300.037630214 1.27160249886092;
243330.396959248 1.61411410292679;
237530.389940994 1.21846939260826];
B = [0.6 0.18; 0.15 0.46]; % green circles
for i=1:2
plot(A(:,1),A(:,2),'r*');
hold on
plot(B(i,1),B(i,2), '-ko',...
'LineWidth',1,...
'MarkerFaceColor',[.49 1 .63],...
'MarkerSize',9);
end
When I ploted A and B, I got this:
B(1,1) = 0.6, but it appears in 0 (X-axis). Same with B(2,1) = 0.15
How to correct this?
A logarithmic scale on the xaxis will help with the view
set(gca, 'XScale', 'log')
However, it will lead to the fact, that now the values of A appear to populate one vertical line.
If you cannot live with this, you may want to try a broken x-axis. MATLAB doesn't support this with build-in functions, but there is a solution in the MATLAB file exchange
https://de.mathworks.com/matlabcentral/fileexchange/3683-breakxaxis
Btw: There is no need for the loop in your code. In fact you plot A twice on top of each other. Just
% Plot A and B without loop
plot(A(:,1), A(:,2),'r*')
hold on
plot(B(:,1), B(:,2), '-ko', 'LineWidth', 1, ...
'MarkerFaceColor', [.49 1 .63], 'MarkerSize',9)
% Set x axis to logarithmic scale
set(gca, 'XScale', 'log')
is sufficient to display your plot
Your x-axis goes from 0 to 250000. On that range, 0.6 and 0.15 are practically 0.
If you want you can use logarithmic scale in x-axis using semilogx

Matlab - adapt xlim and ylim to remove white margin with surfc

I get an issue about the plot of 2d map of a surface with temperature (represented by color). The solution that I plot here is symmetric.
array x represents the array containing the temperature on (sizex,sizey) map size. In my code, sizex = 256 and sizey = 96.
I plot with the following code snippet :
surfc(x);
shading interp;
view([0,0,1]);
hc=colorbar;
set(hc,'position',[0.932 0.3 0.02 0.6]);
caxis([-10 10]);
xlabel('x domain');
ylabel('y domain');
zlabel('temperature');
xlim([0 sizex+2]);
ylim([0 sizey+2]);
and I get the following figure :
As you can see in the script, I added "2" to sizex and sizey to fill a white exterior margin.
If I don't add these values, i.e doing :
xlim([0 sizex]);
ylim([0 sizey]);
Then, I get the following figure :
And you can notice that parts of solution on right and upper sides are not displayed (rather hidden).
You can also see that even on the first figure above (like also for the second figure) (with adding "2" to xlim and ylim), it remains a slight white margin on bottom and I don't know how to remove it.
More precisely, I would like to fit exactly the dimensions of plot with dimensions of the grid data, i.e having temperature over 256x96 size without having margins.
First of all you defined sizex and sizey wrong. I copied your data from pastebin and size(x) yields [258,98] and not [256,96].
Now the other problem that you have is the following: You feed a 2D-Matrix x to surfc. Now what the command does, is putting the value x(1,1) at position (1,1) in the plot. If you don't want these "white borders" you need to put the value at position (0,0) instead. You can achieve that by feeding three matrices X,Y,Z to the surfc-command. You can genereate the matrices as follows:
[X,Y]=meshgrid(0:size(x,2)-1,0:size(x,1)-1);
Z=x;
surfc(X,Y,Z);
% From here on your regular code starts
shading interp;
view([0,0,1]);
hc=colorbar;
set(hc,'position',[0.932 0.3 0.02 0.6]);
caxis([-10 10]);
xlabel('x domain');
ylabel('y domain');
zlabel('temperature');
You should not need to define the limits of the plot now. In case you still need to, use this:
xlim([0,size(x,2)-1]);
ylim([0,size(x,1)-1]);

Ezpolar plots function string over polar axes

I'm using Ezpolar function in order to plot some graphics. Three of them have as maximum value 4, but the last one only has a bit more than 2.
When I plot them, the last one is plotted with it's function over it (seems like if ezpolar paints it some pixels after it maxium value used as radius).
Code and Generated Plot
% This subplot is used since I've 4 graphics to draw.
subplot(2,2,4)
ezpolar('0.25*(5 - 4*cosd(-180 * sin(t) ))');
title('D')
If I don't use this subplot, using a complete figure to draw the graphics seems fine. However, since I need to have all four of them together, it results in (will draw only the problematic one, subplot 2,2,4):
As you can see, r = 0.25 (5 - 4...) is plotted just over the polar axes.
Why is it happening? How can I fix it?
The issue appears to be with the position of that annotation and the fact that when you use a subplot, the limits on the radius of the polar plot actually change but the position of the annotation does not.
To combat this, you could actually compute the limits of the axes and change the position of the text to be explicitly outside of the plot.
hax = subplot(2,2,4);
p = ezpolar('0.25*(5 - 4*cosd(-180 * sin(t) ))');
% Get the handle to the label text object
label = findobj(hax, 'type', 'text');
% Figure out the current axes limits
ylims = get(hax, 'ylim');
% Add some padding (as a percent) to the position
padding = 0.2;
set(label, 'Position', [0 ylims(1)*(1 + padding), 0]);
A better way to do this would be to change the Units of the label to use Normalized units (relative to the axes) rather than Data units. This way, it will not change if the axes limits change.
hax = subplot(2,2,4);
p = ezpolar('0.25*(5 - 4*cosd(-180 * sin(t) ))');
% Get the handle to the label text object
label = findobj(hax, 'type', 'text');
set(label, 'Units', 'Normalized', 'Position', [0.5, -0.2]);

How to keep the subplot sizes unchanged after putting a colorbar

Let us say we have a 1-by-2 subplot and we plot some graphics inside as follows:
subplot(1,2,1)
surf(peaks(20))
subplot(1,2,2)
surf(peaks(20))
And then we want to put a colorbar:
colorbar
I don't want the right figure squezzed as in the result. How can we put the colorbar out of the rightmost figure in a row of subplots and keep the sizes of them unchanged?
Note: Actually, I need it for plotting images where the colorbar is common and I want to put it on the right. I used this toy example for simplicity.
You could just extract the position of the first plot and use on the second. MATLAB automatically moves the colorbar to the right when rescaling.
f1=figure(1);clf;
s1=subplot(1,2,1);
surf(peaks(20));
s2=subplot(1,2,2);
surf(peaks(20));
hb = colorbar('location','eastoutside');
%% # Solution:
s1Pos = get(s1,'position');
s2Pos = get(s2,'position');
s2Pos(3:4) = [s1Pos(3:4)];
set(s2,'position',s2Pos);
%% # Alternative method. Brute force placement
set(s1,'Units','normalized', 'position', [0.1 0.2 0.3 0.6]);
set(s2,'Units','normalized', 'position', [0.5 0.2 0.3 0.6]);
set(hb,'Units','normalized', 'position', [0.9 0.2 0.05 0.6]);
This is just what I was looking for. After implementing Vidar's automatic solution I came up with a simplification. Get the position of the far right axes BEFORE adding the colorbar, and then just reset the squeezed position to the original:
f1=figure(1);clf;
s1=subplot(1,2,1);
surf(peaks(20));
s2=subplot(1,2,2);
surf(peaks(20));
s2Pos = get(s2,'position');
hb = colorbar('location','eastoutside');
set(s2,'position',s2Pos);

Add legend outside of axes without rescaling in MATLAB

I've got a GUI in MATLAB with a set of axes pre-placed. I'm using the location property of the legend to place it to the right hand side of the axes. However, by doing this the axes get re-scaled so that the axes+legend take up the original width of the axes. Is there any way to circumvent the re-size?
Example:
x=0:.1:10;
y=sin(x);
figure
pos=get(gca,'position');
pos(3)=.5; %#re-size axes to leave room for legend
set(gca,'position',pos)
plot(x,y)
So far I get:
Place legend:
legend('sin(x)','location','eastoutside')
...aaaaand...
MATLAB squishes it all into the original axes space. Any way around this?
EDIT
%# create three axes with custom position
x=0:.1:10;
y=sin(x);
hAx1 = axes('Position',[0.05 0.05 0.7 0.2]); plot(hAx1, x,y)
hAx2 = axes('Position',[0.05 0.4 0.7 0.2]); plot(hAx2, x,y)
hAx3 = axes('Position',[0.05 0.75 0.7 0.2]); plot(hAx3, x,y)
%# add legend to middle one
h = legend(hAx2, 'sin(x)'); pos = get(h,'position');
set(h, 'position',[0.8 0.5 pos(3:4)])