matlab plot image as background to graph - matlab

I have an image that I would like to set as the background of plot I am making. However it plots it so that the image taks up the axis([0 1000 0 1000]) while the axis for my graph is much smaller: ([24.5 24.6 67 67.1]). How do I align it so that the image is on the same scale as the graph?
I am performing the following commands:
h = figure;
hold on
voronoi(lats,longs);
I=imread('my_fig.png');
hi = imagesc(I);
set(hi,'alphadata',.5);

You can just call image with the right x and y vectors, like so (assuming your data is in x and y):
xImg = linspace(min(x), max(x), size(I, 2));
yImg = linspace(min(y), max(y), size(I, 1));
image(xImg, yImg, I, 'CDataMapping', 'scaled');
hold on;
plot(x, y);
In other words, generate a vector for each of the dimensions of the image that has the same number of points as that dimension of the image but goes between the range of your data.

Related

How to format graph so that border starts at max x and y and how to replace a plot command

I am trying to format my graph so that the border ends at the max x and max y so there is not extra space between them and the border. Also, I'm trying to completely replace my first plot command with my second one. Should I just delete my first plot? Currently, the second plot goes over my first plot, removing most of my formatting.
clear all, close all
%%command to clear all variables and log history
x = linspace(-pi, pi, 200);
%creating x variable between - pi and 200 with pi distance between each
%value
y = sin(x) + cos(x);
%Creating y varable with the help of x
figure
plot(x,y)
title('2-D Plot')
xlabel('Theta (in radians)')
ylabel('Function Y')
xlim([-pi pi])
ylim([-1.414 1.414])
grid
plot(x,y,'r--')
grid
To fit the axes box tightly around the data without manually adjusting the axis limits, use:
axis tight;
and instead of re-plotting, you can update the relevant properties of the line.
x = linspace(-pi, pi, 200);
y = sin(x) + cos(x);
figure;
h = plot(x,y); %handle for the line plot
title('2-D Plot');
xlabel('Theta (in radians)');
ylabel('Function Y');
grid;
axis tight; %to set the axis limits equal to the range of the data
set(h, 'LineStyle', '--', 'Color', 'r'); %Updating the plot with required changes

PCA on a 3D image to obtain 3 principal axes

I have an anatomical volume image (B), which is an indexed image i,j,k:
B(1,1,1)=0 %for example.
The file contains only 0s and 1s.
I can visualize it correctly with isosurface:
isosurface(B);
I would like to cut the volume at some coordinate in j (it is different for each volume).
The problem is that the volume is tilted vertically, it maybe has 45% degrees, so the cut will not be following the anatomical volume.
I would like to obtain a new orthogonal coordinate system for the data, so my plane in coordinate j would cut the anatomical volume in a more accurate way.
I've been told to do it with PCA, but I don't have a clue how to do it, and reading the help pages haven't been of help. Any direction will be welcome!
EDIT:
I have been following the recommendations, and now I got a new volume, zero-centered, but I think that axes don't follow the anatomical image as they should. These are the pre and post images:
This is the code I used to create the images (I took some code from the answer and the idea from the comments):
clear all; close all; clc;
hippo3d = MRIread('lh_hippo.mgz');
vol = hippo3d.vol;
[I J K] = size(vol);
figure;
isosurface(vol);
% customize view and color-mapping of original volume
daspect([1,1,1])
axis tight vis3d;
camlight; lighting gouraud
camproj perspective
colormap(flipud(jet(16))); caxis([0 1]); colorbar
xlabel x; ylabel y; zlabel z
box on
% create the 2D data matrix
a = 0;
for i=1:K
for j=1:J
for k=1:I
a = a + 1;
x(a) = i;
y(a) = j;
z(a) = k;
v(a) = vol(k, j, i);
end
end
end
[COEFF SCORE] = princomp([x; y; z; v]');
% check that we get exactly the same image when going back
figure;
atzera = reshape(v, I, J, K);
isosurface(atzera);
% customize view and color-mapping for the check image
daspect([1,1,1])
axis tight vis3d;
camlight; lighting gouraud
camproj perspective
colormap(flipud(jet(16))); caxis([0 1]); colorbar
xlabel x; ylabel y; zlabel z
box on
% Convert all columns from SCORE
xx = reshape(SCORE(:,1), I, J, K);
yy = reshape(SCORE(:,2), I, J, K);
zz = reshape(SCORE(:,3), I, J, K);
vv = reshape(SCORE(:,4), I, J, K);
% prepare figure
%clf
figure;
set(gcf, 'Renderer','zbuffer')
% render isosurface at level=0.5 as a wire-frame
isoval = 0.5;
[pf,pv] = isosurface(xx, yy, zz, vv, isoval);
p = patch('Faces',pf, 'Vertices',pv, 'FaceColor','none', 'EdgeColor',[0.5 1 0.5]);
% customize view and color-mapping
daspect([1,1,1])
axis tight vis3d;view(-45,35);
camlight; lighting gouraud
camproj perspective
colormap(flipud(jet(16))); caxis([0 1]); colorbar
xlabel x; ylabel y; zlabel z
box on
Can anybody provide a hint what might be happening? It seems that the problem might be the reshape command, Is it possible that I am canceling out the job previously done?
Not sure about PCA, but here is an example showing how to visualize a 3D scalar volume data, and cutting the volume at a tilted plane (non-axis aligned). Code is inspired by this demo in the MATLAB documentation.
% volume data
[x,y,z,v] = flow();
vv = double(v < -3.2); % threshold to get volume with 0/1 values
vv = smooth3(vv); % smooth data to get nicer visualization :)
xmn = min(x(:)); xmx = max(x(:));
ymn = min(y(:)); ymx = max(y(:));
zmn = min(z(:)); zmx = max(z(:));
% let create a slicing plane at an angle=45 about x-axis,
% get its coordinates, then immediately delete it
n = 50;
h = surface(linspace(xmn,xmx,n), linspace(ymn,ymx,n), zeros(n));
rotate(h, [-1 0 0], -45)
xd = get(h, 'XData'); yd = get(h, 'YData'); zd = get(h, 'ZData');
delete(h)
% prepare figure
clf
set(gcf, 'Renderer','zbuffer')
% render isosurface at level=0.5 as a wire-frame
isoval = 0.5;
[pf,pv] = isosurface(x, y, z, vv, isoval);
p = patch('Faces',pf, 'Vertices',pv, ...
'FaceColor','none', 'EdgeColor',[0.5 1 0.5]);
isonormals(x, y, z, vv, p)
% draw a slice through the volume at the rotated plane we created
hold on
h = slice(x, y, z, vv, xd, yd, zd);
set(h, 'FaceColor','interp', 'EdgeColor','none')
% draw slices at axis planes
h = slice(x, y, z, vv, xmx, [], []);
set(h, 'FaceColor','interp', 'EdgeColor','none')
h = slice(x, y, z, vv, [], ymx, []);
set(h, 'FaceColor','interp', 'EdgeColor','none')
h = slice(x, y, z, vv, [], [], zmn);
set(h, 'FaceColor','interp', 'EdgeColor','none')
% customize view and color-mapping
daspect([1,1,1])
axis tight vis3d; view(-45,35);
camlight; lighting gouraud
camproj perspective
colormap(flipud(jet(16))); caxis([0 1]); colorbar
xlabel x; ylabel y; zlabel z
box on
Below is the result showing the isosurface rendered as wire-frame, in addition to slicing planes both axes-aligned and one rotated. We can see that the volume space on the inside of the isosurface has values equal to 1, and 0 on the outside
I don't think that PCA solves your problem. If you apply PCA to your data it will give you three new axes. These axes are called principal components (PCs). They have the property that the first PC has the largest variance when the data is projected on it. The second PC must also has the largest variance when data is projected on it subject to the constraint that it should be orthogonal to the first, the third PC is similar.
Now the question is when you project your data into the new coordinate system (defined by the PCs) will it match the anatomical volume? Not necessarily and most probably will not. The right axes for your data do not have the optimization objective of PCA.
Sorry, I tried to answer to #Tevfik-Aytekin, but the answer is too long.
Hopefully this answer will be useful for somebody:
Hi #Tevfik, thanks for your answer. I've struggling for days with this same problem, and I think I got it right now.
I think that the difference respect to what you are saying is that I am working with coordinates. When I perform PCA over my coordinates, I get a 3x3 transformation matrix for my data (COEFF matrix, which is unitary and orthogonal, it is just a rotation matrix), so I know that I get exactly the same volume when transformed.
These are the steps I followed:
I had a (I,J,K), 3D volume.
As per #werner suggestion, I changed it to a 4 column matrix (x,y,z,v), size (I*J*K, 4).
Eliminated the coordinates (x,y,z) when v == 0, and v too. So right now, size is (original volume, 3). Only the coordinates with value 1, so the length of the vector is the volume of the figure.
Perform PCA to obtain COEFF and SCORE.
COEFF is a 3x3 matrix. It is unitary and orthogonal, it is a rotation matrix for my volume data.
I did the editing in the PCA1 axis (i.e. delete al values when COEFF(1) is bigger than some-value). This was my problem, I wanted to cut the volume perpendicular to the main axis.
This was enough for me, the reamining coordinates are giving me the volume I wanted. But:
I didn't need to go back, as I just needed the remaining volume, but
In order to go back, I just had to reconstruct the original coordinates. So first I transformed the remaining coordinates with SCORE*COEFF'.
Then I created again a (I*J*K, 4) matrix, making the v column = 1 only when the transformed coordinates matched the new matrix (with ismember, option 'row').
I created the indexed volume back using reshape(v, I, J, K).
If I visualize the new volume back, it is cut perpendicular to the main geometric axes of the figure, just as I needed.
Please, I would really like to hear any comment or suggestion on the method.

Adding space between cells in Matlab imagesc output

I am creating a 2D plot in Matlab by calling this command: imagesc(vector1, vector2, mat_weights). Then, I run the colorbar command.
I now have a smooth 2D plot, but I want to add space between the cells. Here's how I want it to look:
How do I add such spacing between the cells/boxes?
You can add spaces between patches of color using another function than imagesc. Here, scatter provides a straightforward solution when used with option 'filled' and marker 'square'.
Note that you need to transform your 2-D matrix into a vector, but you don't have to scale your data: scatter takes the min and max values from your data and assign them to the min and max colors of the colormap.
The code
% 2-D in 1-D:
Z = diag(1:10); %example of 2-D matrix to be plotted
C = reshape(Z,1,[]); %1-D transform for vector color
% input definition
sz_matrix = 10;
X = repmat( (1:sz_matrix), 1, sz_matrix);
Y = kron(1:sz_matrix,ones(1,sz_matrix));
S = 1000; % size of marker (handle spaces between patches)
%C = (X.^2 + Y.^2); % second color scheme
%plot
figure('Color', 'w', 'position', [10 10 600 400]);
scatter(X, Y, S, C, 'fill', 's');
set(gca, 'XLim', [0 11], 'YLim', [0 11]);
axis square;
colormap summer
colorbar
will give
EDIT
Here is a piece of code for a rectangular matrix. Please note the inversion of the Y axis direction so that the graphical representation matches disp(Z). To have similar (x,y) proportion in the white area separating color patches, one may try to resize manually the figure.
Z = diag(1:10); %example of 2-D matrix to be plotted
Z = Z(1:end-2,:); %trim for rectangular
% input definition
X = repmat(1:size(Z,2), 1, size(Z,1));
Y = kron(1:size(Z,1),ones(1,size(Z,2)));
C = reshape(Z',1,[]); %1-D transform for vector color
S = 1000; % size of marker (handle spaces between patches)
%plot
figure('Color', 'w');
scatter(X, Y, S, C, 'fill', 's');
set(gca, 'XLim', [0 size(Z,2)+1], 'YLim', [0 size(Z,1)+1]);
colormap jet
colorbar
set(gca, 'YDir','reverse');
The ouput:

3D body plot in matlab ( volume visualization )

I have little or no experience with volumetric data in MATLAB,
I need to complete next task:
I have 3 vectors ( rows ):
x_ = vector(1:smpl:max_row,1);
y_ = vector(1:smpl:max_row,2);
z_ = vector(1:smpl:max_row,3);
that are samples from large 3 columns array vector with height max_row.
x_ , y_ , z_ are points of 3D figure - surface points of the figure ( volume ). They represent 3D body that should be drawn in matlab.
I created linear grid:
%linear grid
a = -1.1:step:(-1.1+step*(length(x_)-1));
b = -1.1:step:(-1.1+step*(length(y_)-1));
c = -1.1:step:(-1.1+step*(length(z_)-1));
[x,y,z] = meshgrid(-1.1:step:(-1.1+step*(length(x_)-1)));
and also I create array v length(x_)*length(x_)*length(x_) that contains '1' in cells that are of 3D body representation function points and '0' another.
I tryied to make interpolation:
vi = interp3(x,y,z,v,x,y,z,'nearest');
but then vi = v that I've already created.
Now I need to plot the v array on 3D and form 3D body like in
http://www.mathworks.com/help/techdoc/ref/isonormals.html
for example.
I make that next way:
%plotting:
figure
p = patch(isosurface(x,y,z,v,1e-5,'verbose'),'FaceColor','green','EdgeColor','none');
grid on;
isonormals(v,p);
daspect([1 1 1])
view(3);
axis tight;
camproj perspective;
camlight
lighting gouraud
colormap(hsv)
but I get then only small rectangles in place of function '1' that are not connected like in picture that is attached.
I expect solid body enclosed by that points to be plotted.
Does anybody know what is the problem , how to draw 3D body from the x,y,z,v arrays ?
Thanks in advance.
image:
http://imgur.com/Ulegj
Try this, which will be a nice plot (it interpolates a bit though):
x = vector(1:smpl:max_row,1);
y = vector(1:smpl:max_row,2);
z = vector(1:smpl:max_row,3);
% Settings
displaySurface = 1;
displayPoints = 0;
xres = 800; % Resolution, the higher, the smoother
yres = 800;
cm = 'default'; % Colormap
% Axes Limits
xmin = min(x);
ymin = min(y);
xmax = max(x);
ymax = max(y);
xi = linspace(xmin, xmax, xres);
yi = linspace(ymin, ymax, yres);
% Figure
myfig = figure('Position', [200 200 800 600]);
rotate3d off
[XI, YI] = meshgrid(xi, yi);
ZI = griddata(x, y, z, XI, YI, 'cubic');
mesh(XI,YI,ZI);
colormap(cm)
if(displaySurface == 1)
hold on;
surf(XI, YI, ZI, 'EdgeColor', 'none');
end
hold on;
xlabel('x');
ylabel('y');
zlabel('z');
title('Title', 'FontWeight', 'bold');
xlim([xmin xmax])
ylim([ymin ymax])
grid off;
if(displayPoints == 1)
hold on
plot3(x, y, z,'marker','p','markerfacecolor','w','linestyle','none')
hidden off
end

Plotting several images in the same plot

I'm trying to plot small images on a larger plot... Actually its isomap algorithm, I got many points, now each point correspond to some image, I know which image is it... The porblem is how to load that image and plot on the graph?
One more thing I have to plot both image and the points, so, basically the images will overlap the points.
Certainly, the type of image given here
Something like this should get you started. You can use the low-level version of the image function to draw onto a set of axes.
% Define some random data
N = 5;
x = rand(N, 1);
y = rand(N, 1);
% Load an image
rgb = imread('ngc6543a.jpg');
% Draw a scatter plot
scatter(x, y);
axis([0 1 0 1]);
% Offsets of image from associated point
dx = 0.02;
dy = 0.02;
width = 0.1;
height = size(rgb, 1) / size(rgb, 2) * width;
for i = 1:N
image('CData', rgb,...
'XData', [x(i)-dx x(i)-(dx+width)],...
'YData', [y(i)-dy y(i)-(dy+height)]);
end