The following figure is just a representation of a 2d array with surf. I would like to create a similar figure with 10 of these 2d arrays stacked on top of each other with some kind of offset along the z axis.
figure();
surf(X);
colormap(hsv);
shading interp;
campos([-70 -150 80]);
grid on;
set(gcf,'color','w');
Just call surf several times with hold on, applying a gradually increasing offset.
By default (1-input version of surf), the offset will affect the colors shown for each surface. Here's an example with three 2D arrays. Note that peak-to-peak amplitude is different for each one.
x{1} = .2*peaks(30);
x{2} = .4*peaks(30);
x{3} = .8*peaks(30); % cell array containing three 2D arrays
offset = 7; % desired offset
hold on
for k = 1:numel(x)
surf(x{k} + offset*(k-1))
end
campos([-100 -170 90])
grid on
To prevent offset from affecting color, i.e. achieve consistent color for all surfaces, use the 2- or 4-input version of surf to separately specify height and color:
x{1} = .2*peaks(30);
x{2} = .4*peaks(30);
x{3} = .8*peaks(30);
offset = 7;
hold on
for k = 1:numel(x)
surf(x{k} + offset*(k-1), x{k}) % Only this line has been changed
end
campos([-100 -170 90])
grid on
To generate stacked planes (no height variations) with color depending on value: modify the input arguments as follows:
x{1} = .2*peaks(30);
x{2} = .4*peaks(30);
x{3} = .8*peaks(30);
offset = 7;
hold on
for k = 1:numel(x)
surf(repmat(offset*(k-1), size(x{k})), x{k}) % Only this line has been changed
end
campos([-100 -170 90])
grid on
I've plotted a graph using pcolor which gives me the following graph-
My aim is to use the roof of the graph (by roof) I mean the highest axis (in this case, the line which is defined by y=57) as the base for a further graph.
I was able to use hold on to generate the following-
Code for this (removed some parts that defined the axis labels etc for brevity)-
load sparsemap ;
load d ;
residues = 57 ;
z = zeros(residues,residues); % define the matrix
index = find(sparsemap(:,3) ~= 0) ;
values = length(index);
hold on
%Plots the map you see in the first photo-
for k = 1:values
z(sparsemap(index(k),1),sparsemap(index(k),2)) = sparsemap(index(k),3);
z(sparsemap(index(k),2),sparsemap(index(k),1)) = sparsemap(index(k),3);
end
%Plots the line plot at the bottom of the graph.
A = d(:,1);
B = d(:,2) ;
plot(A, B) ;
pcolor(1:residues,1:residues,z);
works = load('colormap_works');
colormap(works);
colorbar;
As you can see, the line plot is using the same x axis as the first graph.
I am trying to get the line plot to come on top of the figure. I imagine a final figure like so-
Any ideas as to how I can use the top part of the first graph?
You can use 2 subplots. Here is an example:
data = randi(50,20,20); % some data for the pcolor
y = mean(data); % some data for the top plot
subplot(5,1,2:5) % create a subplot on the lower 4/5 part for the figure
pcolor(data) % plot the data
colormap hot;
h = colorbar('east'); % place the colorbar on the right
h.Position(1) = 0.94; % 'push' the colorbar a little more to the right
ax = gca;
pax = ax.Position; % get the position for further thightning of the axes
ax.YTick(end) = []; % delete the highest y-axis tick so it won't interfere
% with the first tick of the top plot
subplot(5,1,1) % create a subplot on the upper 1/5 part for the figure
plot(1:20,y) % plot the top data
ylim([0 max(y)]) % compact the y-axis a little
ax = gca;
ax.XAxis.Visible = 'off'; % delete the x-axis from the top plot
ax.Position(2) = pax(2)+pax(4); % remove the space between the subplots
Which creates this:
I have about four series of data on a Matlab plot, two of them are quite close and can only be differentiated with a zoom. How do I depict the zoomed part within the existing plot for the viewer. I have checked similar posts but the answers seem very unclear.
I look for something like this:
Here is a suggestion how to do this with MATLAB. It may need some fine tuning, but it will give you the result:
function pan = zoomin(ax,areaToMagnify,panPosition)
% AX is a handle to the axes to magnify
% AREATOMAGNIFY is the area to magnify, given by a 4-element vector that defines the
% lower-left and upper-right corners of a rectangle [x1 y1 x2 y2]
% PANPOSTION is the position of the magnifying pan in the figure, defined by
% the normalized units of the figure [x y w h]
%
fig = ax.Parent;
pan = copyobj(ax,fig);
pan.Position = panPosition;
pan.XLim = areaToMagnify([1 3]);
pan.YLim = areaToMagnify([2 4]);
pan.XTick = [];
pan.YTick = [];
rectangle(ax,'Position',...
[areaToMagnify(1:2) areaToMagnify(3:4)-areaToMagnify(1:2)])
xy = ax2annot(ax,areaToMagnify([1 4;3 2]));
annotation(fig,'line',[xy(1,1) panPosition(1)],...
[xy(1,2) panPosition(2)+panPosition(4)],'Color','k')
annotation(fig,'line',[xy(2,1) panPosition(1)+panPosition(3)],...
[xy(2,2) panPosition(2)],'Color','k')
end
function anxy = ax2annot(ax,xy)
% This function converts the axis unites to the figure normalized unites
% AX is a handle to the figure
% XY is a n-by-2 matrix, where the first column is the x values and the
% second is the y values
% ANXY is a matrix in the same size of XY, but with all the values
% converted to normalized units
pos = ax.Position;
% white area * ((value - axis min) / axis length) + gray area
normx = pos(3)*((xy(:,1)-ax.XLim(1))./range(ax.XLim))+ pos(1);
normy = pos(4)*((xy(:,2)-ax.YLim(1))./range(ax.YLim))+ pos(2);
anxy = [normx normy];
end
Note that the units of areaToMagnify are like the axis units, while the units of panPosition are between 0 to 1, like the position property in MATLAB.
Here is an example:
x = -5:0.1:5;
subplot(3,3,[4 5 7 8])
plot(x,cos(x-2),x,sin(x),x,-x-0.5,x,0.1.*x+0.1)
ax = gca;
area = [-0.4 -0.4 0.25 0.25];
inlarge = subplot(3,3,3);
panpos = inlarge.Position;
delete(inlarge);
inlarge = zoomin(ax,area,panpos);
title(inlarge,'Zoom in')
I am trying to make a simple bar graph in MATLAB and whenever the value is zero I want to put a character there. Like an asterisk or something to show that the value for that bar is zero. Is there a way to do this?
Is this what you want?
data = [3.1 4.5 0 6.3 2.7 0 6.1]; %// example data
H = -.008; %// horizontal offset relative to axis span. Set as needed
V = .03; %// vertical offset relative to axis span. Set as needed
h = bar(data); %// plot data
xdata = get(h, 'XData'); %// get x data from plot
ydata = get(h, 'YData'); %// get y data from plot
ind = ydata==0; %// logical index of zero-height data
xl = xlim; %// span of x axis
yl = ylim; %// span if y axis
hoffset = xl(1)+xl(2)*H; %// compute horizontal offset
voffset = yl(1)+yl(2)*V; %// compute vertical offset
text(xdata(ind)+hoffset, repmat(voffset,1,sum(ind)), '*', 'fontsize', 12) %// create text
I try to use the Matlab function gradient to calculate the gradient of a volume. I use quiver to display the gradients of slices.
I use a cube-like volume, which is symmetric with respect to x, y, and z axis. To my surprise, the result is not the same for all slices. Actually only the result in the xy-plane (Z-slice, last image) is the expected result.
I know that there are issues when calculating the gradient at the border of an image. But for me the result at the border is not important and so I don't care if the result next to the border is correct. For me it would be important that all three images look like the last one.
Can somebody tell me what is wrong with my code? Thanks!
f=zeros(20,20,20);
space = 5;
f(:,:,space) = 1; f(:,:,end-space) = 1;
f(:,space,:) = 1; f(:,end-space,:) = 1;
f(space,:,:) = 1; f(end-space,:,:) = 1;
space = 4;
f(:,:,space) = 1; f(:,:,end-space) = 1;
f(:,space,:) = 1; f(:,end-space,:) = 1;
f(space,:,:) = 1; f(end-space,:,:) = 1;
size_iso = size(f);
x_slice = round(size_iso(1)/2);
y_slice = round(size_iso(2)/2);
z_slice = round(size_iso(3)/2);
% display the gradient of the edge map
[fx,fy,fz] = gradient(f,0.1);
figure;
image(squeeze(f(x_slice,:,:))*50); colormap(gray(64)); hold on;
quiver(squeeze(fy(x_slice,:,:)),squeeze(fz(x_slice,:,:)));
axis equal;
title(['edge map gradient of X-slice ', num2str(x_slice)]);
figure;
image(squeeze(f(:,y_slice,:))*50); colormap(gray(64)); hold on;
quiver(squeeze(fx(:,y_slice,:)),squeeze(fz(:,y_slice,:)));
axis equal;
title(['edge map gradient of Y-slice ', num2str(y_slice)]);
figure;
image(squeeze(f(:,:,z_slice))*50); colormap(gray(64)); hold on;
quiver(squeeze(fx(:,:,z_slice)),squeeze(fy(:,:,z_slice)));
axis equal;
title(['edge map gradient of Z-slice ', num2str(z_slice)]);
Things are bit more complicated with 3D matrices and coordinates.
For example
img = rand(10,30);
imagesc(img);
axis equal;
will display an image 30 pixels wide and 10 pixels high.
In MatLab when you display an image its first dimension (rows) is actually Y-axis on the plot. Second dimension (columns) is X-axis on the plot.
See, for example, http://www.mathworks.com/help/matlab/math/multidimensional-arrays.html
To illustrate mistake in your code consider simplified example:
% we need a 3D matrix with
% 10 points along the X-axis
% 20 points along the Y-axis
% 30 points along the Z-axis
f = rand(20,10,30); % note the order of numbers
size_iso = size(f), % gives [20 10 30]
x_slice = round(size_iso(2)/2) % gives 5
y_slice = round(size_iso(1)/2) % gives 10
z_slice = round(size_iso(3)/2) % gives 15
figure;
image(squeeze(f(:,x_slice,:))*50); colormap(gray(64)); hold on;
axis equal;
title(['X-slice ', num2str(x_slice)]);
% this code produces image 30 pixels wide and 20 pixels high
% Thus 1st dimension (vertical axis) is actually the Y-axis
% Thus 2nd dimension (horizontal axis) is actually the Z-axis
figure;
image(squeeze(f(y_slice,:,:))*50); colormap(gray(64)); hold on;
axis equal;
title(['Y-slice ', num2str(y_slice)]);
% this code produces image 30 pixels wide and 10 pixels high
% Thus 1st dimension (vertical axis) is actually the X-axis
% Thus 2nd dimension (horizontal axis) is actually the Z-axis
figure;
image(squeeze(f(:,:,z_slice))*50); colormap(gray(64)); hold on;
axis equal;
title(['Z-slice ', num2str(z_slice)]);
% this code produces 10 pixels wide and 20 pixels high
% Thus 1st dimension (vertical axis) is actually the Y-axis
% Thus 2nd dimension (horizontal axis) is actually the X-axis
For your code to work properly you should pay attention not only to the order of dimensions in the slice image but also to the way they are shifted by squeeze function.
Therefore you should provide proper combination of coordinates to the subsequent quiver function call.
I modified your code to fill slab perpendicular to given axis with unique value so you should be able to distinguish them easier. Also I'm using different dimensions along each axis for the same purpose.
xvalue=0.33;
yvalue=0.66;
zvalue=1.00;
% we need a 3D matrix with
% 10 points along the X-axis
% 20 points along the Y-axis
% 30 points along the Z-axis
f = zeros(20,10,30); % note the order of numbers
space = 3;
f(:,space,:) = xvalue; f(:,end-space,:) = xvalue;
f(space,:,:) = yvalue; f(end-space,:,:) = yvalue;
f(:,:,space) = zvalue; f(:,:,end-space) = zvalue;
size_iso = size(f);
x_slice = round(size_iso(2)/2); % note dimension number here for x_slice
y_slice = round(size_iso(1)/2); % note dimension number here for y_slice
z_slice = round(size_iso(3)/2);
% display the gradient of the edge map
[fx,fy,fz] = gradient(f,0.1);
figure;
image(squeeze(f(:,x_slice,:))*50); colormap(gray(64)); hold on;
quiver(squeeze(fz(:,x_slice,:)),squeeze(fy(:,x_slice,:)));
axis equal;
title(['edge map gradient of X-slice ', num2str(x_slice)]);
xlabel('Z')
ylabel('Y')
figure;
image(squeeze(f(y_slice,:,:))*50); colormap(gray(64)); hold on;
quiver(squeeze(fz(y_slice,:,:)),squeeze(fx(y_slice,:,:)));
axis equal;
title(['edge map gradient of Y-slice ', num2str(y_slice)]);
xlabel('Z')
ylabel('X')
figure;
image(squeeze(f(:,:,z_slice))*50); colormap(gray(64)); hold on;
quiver(squeeze(fx(:,:,z_slice)),squeeze(fy(:,:,z_slice)));
axis equal;
title(['edge map gradient of Z-slice ', num2str(z_slice)]);
xlabel('X')
ylabel('Y')
Yes, this is tricky and hard to understand at first but you'll get used to it with practice.