How to position bars along side the X axis in bar3? - matlab

I am trying to plot bars using bar3 on a background image. Although the bar3 command is able to move the bars alongside the Y-axis, I have no idea how to move the bars in the X-axis direction.
This is an example of what I use, but still cannot move the bars in the X-axis.
A = [10 5 20 8];
bar3(1:4, A)
xlabel('x'); ylabel('y');
Do you have any ideas how to move the bars to the desired position? Thanks!

You can modify the X coordinate of your bars after they have been created and move them where ever you want them. The example below moves the 4 bars in your example, output img shown below.
f = figure;
ax = axes ( 'parent', f );
A = [10 5 20 8];
h = bar3(ax, 1:4, A );
xlabel('x');
ylabel('y');
% create some new positions for the xdata
index = randperm(4);
% the xdata is blocks on 6x4 coordinates
start = 1;
for ii=1:4
finish = start+5;
% for each block of data update the x co-ordinate
% this will "move" if along the x-axis
h.XData(start:finish,:)=h.XData(start:finish,:)+index(ii);
start = finish+1;
end
% Update the xlim of the axes to display them
ax.XLim = [0 5];

Related

Add error bars to grouped bar plot in MatLab

I have a simple, grouped bar plot. I'm trying to plot the error bars, too, but I can't seem to figure it out.
I'm not too great with for loops, but I don't know if that's the only solution to this, or if I can just add another line of code to plot the error bars.
Here's my code and graph:
% Plot raw data
y = [316.45 292.14 319.96; 305.59 287.99 295.21] % first 3 #s are pre-test, second 3 #s are post-test
err = [13.12 5.67 12.36; 12.43 6.83 11.67]
box on
bar(y)
set(gca,'xticklabel',{'Pre-test'; 'Post-test'})
ylim([200 360])
ylabel('RT (ms)')
xlabel('Session')
Here is a solution using the standard errorbar and bar functions. bar plots each group at the same x position, and uses the Xoffset property to shift the bars in a group. You can use the x position and Xoffset to plot the errorbars.
% Data
y = [316.45 292.14 319.96; 305.59 287.99 295.21] % first 3 #s are pre-test, second 3 #s are post-test
err = [13.12 5.67 12.36; 12.43 6.83 11.67]
% Plot
figure(1); clf;
hb = bar(y); % get the bar handles
hold on;
for k = 1:size(y,2)
% get x positions per group
xpos = hb(k).XData + hb(k).XOffset;
% draw errorbar
errorbar(xpos, y(:,k), err(:,k), 'LineStyle', 'none', ...
'Color', 'k', 'LineWidth', 1);
end
% Set Axis properties
set(gca,'xticklabel',{'Pre-test'; 'Post-test'});
ylim([200 360])
ylabel('RT (ms)')
xlabel('Session')

Using roof of a graph as x-axis for another

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:

hist3 plot with additional z axis

The following code creates a 2D stacked histogram for two 2D distributions:
%%first dataset
x1 = 200 + 300.*rand(1000,1)'; %rand values between 0 and 200
y1 = 100 + 250.*rand(1000,1)'; %rand values between 100 and 500
%%secnd dataset
x2 = 100 + 200.*rand(1000,1)'; %rand values between 0 and 200
y2 = 200 + 400.*rand(1000,1)'; %rand values between 100 and 500
one = linspace(100,400,20);
two = linspace(100,500,20);
EDGES = {one, two}; %edges
[n1,c1] = hist3([x1' y1'],'Edges',EDGES);%first dataset
[n2,c2] = hist3([x2' y2'],'Edges',EDGES);%second dataset
figure('Color','w');
% plot the first data set
bh=bar3(n1);
% Loop through each row and shift bars upwards
for ii=1:length(bh)
zz = get(bh(ii),'Zdata');
kk = 1;
% Bars are defined by 6 faces(?), adding values from data2 will
% shift the bars upwards accordingly, I'm sure this could be made
% better!
for jj = 0:6:(6*length(bh)-6)
zz(jj+1:jj+6,:)=zz(jj+1:jj+6,:)+n2(kk,ii);
kk=kk+1;
end
%erase zero height bars
%# get the ZData matrix of the current group
Z = get(bh(ii), 'ZData');
%# row-indices of Z matrix. Columns correspond to each rectangular bar
rowsInd = reshape(1:size(Z,1), 6,[]);
%# find bars with zero height
barsIdx = all([Z(2:6:end,2:3) Z(3:6:end,2:3)]==0, 2);
%# replace their values with NaN for those bars
Z(rowsInd(:,barsIdx),:) = NaN;
%# update the ZData
set(bh(ii), 'ZData',Z)
end
% Set face colour to blue for data1
set(bh,'FaceColor',[0 0 1]);
% Apply hold so that data2 can be plotted
hold on;
% Plot data2
bh=bar3(n2);
%erase zero height bars
for ii=1:numel(bh)
%# get the ZData matrix of the current group
Z = get(bh(ii), 'ZData');
%# row-indices of Z matrix. Columns correspond to each rectangular bar
rowsInd = reshape(1:size(Z,1), 6,[]);
%# find bars with zero height
barsIdx = all([Z(2:6:end,2:3) Z(3:6:end,2:3)]==0, 2);
%# replace their values with NaN for those bars
Z(rowsInd(:,barsIdx),:) = NaN;
%# update the ZData
set(bh(ii), 'ZData',Z)
end
% Set face color to red
set(bh,'FaceColor',[1 0 0]);
%set ticks
set(gca,'XTick',1:6:numel(one),'XTickLabel',one(1:6:end))
set(gca,'YTick',1:6:numel(one),'YTickLabel',one(1:6:end))
view(20,40)
%labels
xlabel('x')
ylabel('y')
zlabel('z')
%set transparency
set(gcf,'renderer','opengl');
set(get(gca,'child'),'FaceAlpha',0.8);
set(get(gca,'child'),'EdgeAlpha',0.3);
A first issue is the transparency (but I think it is a problem of my matlab version 2014a, so I am not bothered by that). It just makes all blurry.
My question is how to add a mesh plot on the same picture. The code creating the meshes is the following:
%create surface I want to plot
[X,Y] = meshgrid(one,two);
inds1=find(X(:).*Y(:)<.3e5);%condition
inds2=find(X(:).*Y(:)>.3e5);
I=Y./X.^2;%first surface
I(inds1)=NaN;%second surface
figure('Color','w');hold on
mesh(X,Y,I,'FaceColor',[0 0 1],'EdgeColor','none')
I(:,:)=NaN;
I(inds1)=Y(inds1)./X(inds1);%second surface
mesh(X,Y,I,'FaceColor',[1 0 0],'EdgeColor','none')
alpha(.5)
grid on
view(20,40)
%labels
xlabel('x')
ylabel('y')
zlabel('z')
The domain of the histograms and the meshes are the same. So I just need to add an extra z-axis on the first figure.
I tried substituting figure('Color','w');hold on in the second code with AxesH = axes('NextPlot', 'add');, but I was really wrong about that:
That just overlayed the two figures..
I also tried something along the lines of:
%add axis
axesPosition = get(gca,'Position'); %# Get the current axes position
hNewAxes = axes('Position',axesPosition,... %# Place a new axes on top...
'Color','none',... %# ... with no background color
'ZLim',[0 400],... %# ... and a different scale
'ZAxisLocation','right',... %# ... located on the right
'XTick',[],... %# ... with no x tick marks
'YTick',[],... %# ... with no y tick marks
'Box','off');
but it is not feasible because the property ZAxisLocation does not exist.
Does anyone know how to add the z-axis?
Also, if you have other comments on how to ameliorate the code, they're welcome!
acknowledgements
2d stacked histogram:https://stackoverflow.com/a/17477348/3751931
erasing the zero values in the hist plot: https://stackoverflow.com/a/17477348/3751931
I now think that this is not yet possible (http://www.mathworks.com/matlabcentral/answers/95949-is-there-a-function-to-include-two-3-d-plots-with-different-z-axes-on-the-same-plot-area-similar-to).
So I just added a fake axis:
[X,Y] = meshgrid(one,two);
inds1=find(X(:).*Y(:)<.3e5);%condition
inds2=find(X(:).*Y(:)>.3e5);
s=Y./X.^2;%first surface
s(inds1)=NaN;%second surface
%mesh(X,Y,I,'FaceColor',[0 0 1],'EdgeColor','none')
mesh((X-min(min(X)))/max(max(X-min(min(X))))*20,(Y-min(min(Y)))/max(max(Y-min(min(Y))))*20,...
s/max(max(s))*max(max(n1))+max(max(n1)),'FaceColor','g','EdgeColor','none','facealpha',.5)
s(:,:)=NaN;
s(inds1)=Y(inds1)./X(inds1);%second surface
%mesh(X,Y,I,'FaceColor',[1 0 0],'EdgeColor','none')
mesh((X-min(min(X)))/max(max(X-min(min(X))))*20,(Y-min(min(Y)))/max(max(Y-min(min(Y))))*20,...
s/max(max(s))*max(max(n1))+max(max(n1)),'FaceColor','y','EdgeColor','none','facealpha',.5)
alpha(.5)
grid on
%add fake z axis
line([20 20],[1 1],[max(max(n1))-min(min(s)) 20],...
'color','g','linewidth',2)
% text(20*ones(1,5),zeros(1,5),linspace(max(max(n1))-min(min(I)),20,5),...
% num2str(linspace(0,max(max(I)),5)),'color','g')
z=linspace(max(max(n1))-min(min(s)),20,5);
txto=linspace(0,max(max(s)),5);
for ii=1:5
line([20 20.3],[1 1],[z(ii) z(ii)],'color','g')%ticks
text(20,0,z(ii),num2str(txto(ii)),'color','g')%ticklabel
end
text(19.8,1,21,'s','color','g')%label
Over all the code is quite ugly and needs a lot of tuning..

Zoom region within a plot in Matlab

I'm using Matlab to produce figures, and I'm wondering if there is a way to plot a zoomed region in a figure of the overall data?
I have scatter data plotted over one week, with the x-axis in hours, and I want to zoom into the first 3 hours, and display them within the main figure with the x-axis label of minutes.
The plotting code I have so far is as follows:
allvalsx = marabint(:,2)
allvalsy = marabint(:,5)
subvalsx = marabint(1:7,2);
subvalsy = marabint(1:7,2);
%% Plots the scatter chart.
sizemarker = 135
handle = scatter(allvalsx, allvalsy, sizemarker, '.')
figure(1)
axes('Position',[.2 .2 .2 .2])
handle2 = scatter(subvalsx, subvalsy, '.r')
title(plotTitle)
xlabel('Time since treatment (hours)')
ylabel('Contact angle (deg)')
% Axis scales x1, x2, y1, y2
axis([0, marabint(length(marabint),2) + 10, 0, 120]);
% This adds a red horizontal line indicating the untreated angle of the
% sample.
untreatedLine = line('XData', [0 marabint(length(marabint),2) + 10], 'YData', [untreatedAngle untreatedAngle], 'LineStyle', '-', ...
'LineWidth', 1, 'Color','r');
% Adding a legend to the graph
legendInfo = horzcat('Untreated angle of ', untreatedString)
hleg1 = legend(untreatedLine, legendInfo);
% This encases the plot in a box
a = gca;
% set box property to off and remove background color
set(a,'box','off','color','none')
% create new, empty axes with box but without ticks
b = axes('Position',get(a,'Position'),'box','on','xtick',[],'ytick',[]);
% set original axes as active
axes(a)
% link axes in case of zooming
linkaxes([a b])
set(gcf,'PaperUnits','inches');
set(gcf,'PaperSize', [8.267 5.25]);
set(gcf,'PaperPosition',[0 0.2625 8.267 4.75]);
set(gcf,'PaperPositionMode','Manual');
set(handle,'Marker','.');
print(gcf, '-dpdf', '-r150', horzcat('markertest4.pdf'));
This produces the following
Can anyone help me out with this?
yeah, I think I know what you need. Try this:
zoomStart = 0;
zoomStop = 3;
set(gca, 'XLim', [zoomStart zoomStop])
Let me know if that doesn't do what you need, and I'll give you a different way.

Plot many horizontal Bar Plots in the same graph

I need to plot a x-y function, that shows the histograms at x-values. Something similar to the bottom plot of the next figure:
I tried to use matlab's "barh", but can't plot many in the same figure.
Any ideas?
Or, maybe displacing the origin (baseline, basevalue in barseries properties) of successive plots would work. How could I do that for barh?
thanks.
Using 'Position' of axes property
% generate "data"
m = rand( 40,10 );
[n x] = hist( m, 50 );
% the actual plotting
figure;
ma = axes('Position',[.1 .1 .8 .8] ); % "parent" axes
N = size(n,2); % number of vertical bars
for ii=1:N,
% create an axes inside the parent axes for the ii-the barh
sa = axes('Position', [0.1+(ii-1)*.8/N, 0.1, .8/N, .8]); % position the ii-th barh
barh( x, n(:,ii), 'Parent', sa);
axis off;
end