MATLAB - Axis equal and meanwhile stretch-to-fill? - image

By default, stretch-to-fill is on. So
pixels = ones(100,100)
image(pixels);
colormap([0 0 0; 1 1 1]);
produces
Forcing the axes to be of the same scale, this
pixels = ones(100,100)
image(pixels);
colormap([0 0 0; 1 1 1]);
axis equal;
produces
Obviously, stretch-to-fill is overridden by axis equal. What to do to make them co-exist?

I think you are looking for this call:
figure(1)
image(pixels)
colormap(clr)
axis image % <-- this call
Here is a table of the axes properties manipulated by the various axis modes:
You can also do something similar using the imshow function, which acts as a higher-level wrapper to image/imagesc:
figure(2)
imshow(pixels, clr, 'InitialMag','fit', 'Border','loose')
axis on

The problem is, your axis limits reflect the old size. Maybe there is a generic way to solve it, but setting the limits manually solves it:
xlim([1,100]);ylim([1,100])

Related

How to used linspace matlab function to get the and the y of all pixels in image?

I have an image of 200x200 * 3, and I should to find the x and the y of each pixel of the image by using the linspace Matlab function.
I have already used the mesh grid function with the following code:
Ny=200; % # pixels in y direction
Nx=200; % # pixels in x direction
resolution=1; % size of a pixel
img=rand(Ny,Nx,3); % random image
y=(img(1:Ny))*resolution-resolution/2;
x=(img(1:Nx))*resolution-resolution/2;
[x,y]=meshgrid(x,y);
But my supervisor told me to use the function linspace and I cannot understand how.Can someone help me please
The only reason I can think of that your supervisor wants you to use linspace is for creating the x and y vector inputs to meshgrid. linspace alone is not sufficient to generate all of the pixel coordinates, so you'll have to use meshgrid, ndgrid, repelem or repmat.
The one advantage that linspace has over simply doing something like 1:resolution:Ny is that linspace ensures that the endpoints always appear in the range. For example, if you do
>> 1:.37:4
ans =
1.0000 1.3700 1.7400 2.1100 2.4800 2.8500 3.2200 3.5900 3.9600
you don't get 4 as the last point. However, if you use linspace:
>> linspace(1,4,9)
ans =
1.0000 1.3750 1.7500 2.1250 2.5000 2.8750 3.2500 3.6250 4.0000
the spacing is automatically adjusted to make the last element 4.
So assuming that resolution is the multiplier for the number of points you want, for 2 you want 401 evenly spaced points and for 1/2 you want 101 points, your code would look something like this:
x_points = linspace(1, Nx, Nx*resolution+1);
y_points = linspace(1, Ny, Ny*resolution+1);
(I'm still not sure what the resolution/2 part is supposed to do, so we'll need to clarify that.)
Then you would pass those to meshgrid:
[X,Y] = meshgrid(x_points, y_points);

Matlab change figure size to properly save to .png

I have a plot I get from matlab, with the x-axis ranging from 0 to 1864 values. I want to save this plot as a .png image without need to modify the original .fig file manually
My plot looks like this:
As you can see, the last two numbers are overlapping. The reason is that when matlab displays my image, the popup window is too small. I already tried to change the axes ratio using daspect, but it does not work.
What I think could work is to use the function truesize, my problem is that when I try to use it, I receive the following error:
No images or texturemapped surfaces in the figure.
My code looks like this:
x = rand (1864,1);
F = bar (x);
xlim ([0 1864]);
set(gca, 'XTick', sort([1864, get(gca, 'XTick')]));
truesize(1,[100 100])
Why does this happen? How can I fix this problem in order to save the images preventing x labels overlapping?
You could try rotating your x labels using the following code:
x = rand (1864,1);
F = bar (x);
xlim ([0 1864]);
set(gca, 'XTick', sort([1864, get(gca, 'XTick')]));
set(gca, 'XTickLabelRotation', 90)
Note that you can change the degrees to rotate to other number besides 90 if you wanted.
It gives you a plot that looks like this:

Remove spacing in matlab subplot

How should i remove the empty space between these images?i need to combine all these images without any space.
bot=imread('bot.jpeg');
for i= 1:25
subplot(5,5,i),imshow(bot);
end
You need to specify axes' 'Position' property when you create them with subplot.
Also, you have to adjust figure aspect ratio to match that of the image, so that all figures fit without vertical or horizontal space.
If you show a different image in each subplot, all images should have the same aspect ratio, otherwise it's not possible for them to fit in the figure without empty spaces.
bot = imread('peppers.png');
for i= 1:25
subplot('Position',[(mod(i-1,5))/5 1-(ceil(i/5))/5 1/5 1/5])
imshow(bot); %// or show a different image on each subplot
end
p = get(gcf,'Position');
k = [size(bot,2) size(bot,1)]/(size(bot,2)+size(bot,1));
set(gcf,'Position',[p(1) p(2) (p(3)+p(4)).*k]) %// adjust figure x and y size
The most canonical way would be to take a look at this answer by bla here. This answer uses a function from the MATLAB File Exchange in order to achieve the answer. However, that requires learning a new function and playing around with the parameters.
If you want something working immediately, instead of showing each subimage in a separate grid on a plot, I would simply create a new image that stacks all of those images together:
bot_new = repmat(bot, [5 5]);
imshow(bot_new);
repmat takes a matrix and duplicates / stacks / tiles itself together for as many rows and as many columns (or in any dimension) that you want. In this case, I chose to stack the image so that there are 5 rows and 5 columns of it. We next show the stacked image together with imshow.
If we used an example image from MATLAB:
bot = imread('onion.png');
If we ran the above code that tiles the images together and showed the image, this is what we get:
I copy the answer from mathworks:
For each subplot, store its handle.
h = subplot(2,3,1);
Then set the 'position' property of h to be anything you want.
p = get(h, 'pos');
This is a 4-element vector [left, bottom, width, height] which
by default is in normalized coordinates (percentage of
figure window). For instance, to add 0.05 units (5% of
figure window) to the width, do this:
p(3) = p(3) + 0.05;
set(h, 'pos', p);
The SUBPLOT command picks standard values for these
parameters, but they could be anything you want. You
could put axes anywhere on the figure you want,
any size you want.
You can check for it:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/144116

imagesc() in Matlab not showing equal axis

I use the following lines of code to plot the images:
for t=1:subplotCol
subplot(subplotRow,subplotCol,t)
imagesc([1 100],[1 100],c(:,:,nStep*t));
colorbar
xlabel('X-axis')
ylabel('Y-axis')
title(['Concentration profile at t_{',num2str(nStep*t),'}'])
subplot(subplotRow,subplotCol,subplotCol+t)
hold on;
plot(distance,gamma(:,1,t),'-ob');
plot(distance,gamma(:,2,t),'-or');
plot(distance,gamma(:,3,t),'-og');
xlabel('h');ylabel('\gamma (h)');
legend(['\Theta = ',num2str(theta(1))],...
['\Theta = ',num2str(theta(2))],['\Theta = ',num2str(theta(3))]);
end
I get the following subplot with images:
As you can see the images in first row are now scaled equally on X and Y axis (Y axis is longer than the X-axis) even though the size of the image matrix is 100x100 for each image on first row.
Can someone help with how to make images in first row look like squares than rectangles which I get currently. Thanks.
Use the dataAspectRatio properties of the axes, and set it to [1 1 1]
%# create a test image
imagesc(1:10,1:10,rand(10))
%# you should use the handle returned by subplot
%# instead of gca
set(gca,'dataAspectRatio',[1 1 1])
Another method is to use the command axis equal
Regarding the size of different objects, you can set the exact position of each axes on the figure, for example for the first one use:
subplot(2,2,1); set(gca,'Position',[0.05 0.05 0.4 0.4])

How to lock image dimensions in MATLAB

So I have this matrix in MATLAB, 200 deep x 600 wide. It represents an image that is 2cm deep x 6cm wide. How can I plot this image so that it is locked into proper dimensions, i.e. 2cm x 6cm? If I use the image or imagesc commands it stretches it all out of shape and shows it the wrong size. Is there a way to lock it into showing an image where the x and y axes are proportional?
Second question, I need to then set this image into a 640x480 frame (20 pixel black margin on left and right, 280 pixel black margin on bottom). Is there a way to do this?
To keep aspect ratio, you can use axis equal or axis image commands.
Quoting the documentation:
axis equal sets the aspect ratio so that the data units are the same in every direction. The aspect ratio of the x-, y-, and z-axis is adjusted automatically according to the range of data units in the x, y, and z directions.
axis image is the same as axis equal except that the plot box fits tightly around the data`
For second question:
third_dimension_size=1; %# for b&w images, use 3 for rgb
framed_image=squeeze(zeros(640,480,third_dimension_size));
framed_image(20:20+600-1,140:140+200-1)= my_600_200_image;
imagesc(framed_image'); axis image;
set(gca,'DataAspectRatio',[1 1 1])
Second question:
new_image = zeros(480,640);
new_image(20:(200+20-1),20:(600+20-1)) = old_image;
As an alternative to the other answers, you might want:
set(gca, 'Units', 'centimeters', 'Position', [1 1 6 2])
Make sure you do this after plotting the image to get the other axis properties correct.
For the second question, take care with the number of colour channels:
new_image = zeros(480,640, size(old_image));
new_image(20:(200+20-1),20:(600+20-1),:) = old_image;

Resources