Multiple axes for a single surf plot - matlab

I have a surf plot, in which I would like to have two y-axes. I cannot seem to find any other discussion quite like this.
The closest I got so far is:
surf(peaks);
view(0,0)
ax(1) = gca;
axPos = ax(1).Position;
ax(2) = axes('Position',axPos, 'Color', 'none','XTick',[],'ZTick',[],'YAxisLocation','right');
linkprop(ax, 'CameraPosition');
rotate3d on

% Desired plot
surf(peaks);
% Save axis
ax(1) = gca;
% Use the position of the first axis to define the new axis
pos = ax(1).Position;
pos2 = pos - [0.08 0 0 0];
ax(2) = axes('Position',pos2,'Color', 'none');
% Plot random line in 3D, just make sure your desired axis is correct
plot3(ones(length(peaks),1), 10:10:length(peaks)*10,...
ones(length(peaks),1), 'Color','none')
% Make plot, and non-desired axes, invisible
set(gca,'zcolor','none','xcolor','none','Color','none')
% Link axes
linkprop(ax, 'View');

Related

matlab plot with multiple colormaps

I want to create a plot with pcolor plot with an contour plot on top. Both with different colormaps - pcolor with "hot", the contour with "gray".
I newer Matlab version multiple colormaps are possible.
The code works, however both axis do not overlap, even if the axes positions are in sync.
%% prepare Data
Data2D = peaks(100);
Data2D = Data2D -min(Data2D(:));
Data2D = Data2D/max(Data2D(:)) * 100;
steps = 0:05:100;
xAxis = 1:size(Data2D,2);
yAxis = 1:size(Data2D,1);
figure(1); clf
ax1 = axes;
hold on;
% 3D flat plot
caxis([0 100]);
cmap = fliplr(jet(1000));
colormap(ax1, cmap(1:800,:));
hplot = pcolor(ax1, xAxis, yAxis, Data2D);
shading flat; % do not interpolate pixels
set(ax1,'XLim',[xAxis(1) xAxis(end)]);
set(ax1,'YLim',[yAxis(1) yAxis(end)]);
% colorbar
hcb = colorbar('location','EastOutside');
set(hcb, 'Ylim', [0 100]);
%% contour plot
ax2 = axes; linkaxes([ax1,ax2])
colormap(ax2, flipud(gray(1000)));
[C,hfigc] = contour(ax2, xAxis, yAxis, Data2D,steps);
% Hide the top axes
ax2.Visible = 'off';
ax2.XTick = [];
ax2.YTick = [];
set(hfigc, 'LineWidth',1.0);
hold off;
drawnow
If you didn't use ax2.Visible = 'off' you would probably see that the axes' positions are different, since the first axes are squashed to allow room for the colorbar which the second axes don't have.
TL;DR
You need to set the position properties to be equal
ax2.Position = ax1.Position
Demo
You can simulate this with a blank figure:
1.
% Create figure and first axes, which have a colorbar
figure(1)
ax1 = axes();
colorbar('location', 'eastoutside');
Output:
2.
% Add new axes
hold on;
ax2 = axes();
Output (notice the second axes fills the space of the first + colorbar):
3.
% Make the same, so that the second axes also allow for the colorbar
ax2.Position = ax1.Position;
Output (notice thicker numbers showing they are overlapping fully):

colorbar eastoutside vs westoutside

I put two colorbars in the same image using this submission on filexchange.
The position of the first colorbar is set by:
colorbar('WestOutside')
the position of the second one by:
colorbar('EastOutside')
Does anyone know why the first one is longer?
When looking at the Matlab documentation it seemed to me that they should be the same. What am I missing?
The skeleton of the code is the following:
%define coordinates of the nodes
theta=linspace(0,2*pi,33);
[x,y]=pol2cart(theta,1);
%define colormap of the links
cm = winter;
colormap(cm);
%plot the links
for ii=1:N
quiver(...)
end
%place the first colorbar
hcb=colorbar('EastOutside');
%freeze the first colorbar
cbfreeze(hcb);
%define the second colormap
cm = autumn;
colormap(cm);
%plot the dots
for ii=1:N
plot(...)
end
%place the second colorbar
hb=colorbar('EastOutside');
The key is to use two different axes. Based on your code:
%define coordinates of the nodes
theta=linspace(0,2*pi,33);
[x,y]=pol2cart(theta,1);
%plot the links
close
figure;
for ii=1:100
quiver(x,y)
end
%define colormap of the links
ax1 = gca;
colormap (ax1,winter)
%place the first colorbar
hcb=colorbar(ax1,'EastOutside');
%this is tentative, just to get the axes right position:
hb=colorbar(ax1,'WestOutside');
pos = ax1.Position;
hb.delete
% second colorbar
ax2 = axes;
colormap (ax2,autumn)
hb=colorbar(ax2,'WestOutside');
ax2.Position = pos;
axis off
ax1.Position = pos;
It creates this:
Using MATLAB 2015a.

Colorbar height is too large and overlapping figure title

I have a three-dimensional density distribution and create a figure with two subplots. One of the XY plane and one of the YZ plane. For both figures I want a correct colorbar and for some reason the XY plane colorbar is perfect and the YZ plane colorbar is too big and overlaps the figure title. See below for my code and an image of result. EDIT: added functioning example at bottom
%// Data slice in the XY plane
subplot(1,2,1)
h=slice(xi,yi,zi,density,[],[],0);
set(h,'edgecolor','none');
caxis([-8,-2])
colormap(jet);
c = colorbar;
c.Label.String = 'Density in log 10 scale';
view(2)
daspect([1 1 1])
xlabel('X-axis [km]')
ylabel('Y-axis [km]')
zlabel('Z-axis [km]')
title_orbit = ['Mg sputtering in orbital plane at orbit angle ',is];
title({title_orbit,''})
%// Data slice in the YZ plane
subplot(1,2,2)
g=slice(xi,yi,zi,density,0,[],[]);
set(g,'edgecolor','none');
caxis([-8,-2])
colormap(jet);
d = colorbar;
d.Label.String = 'Density in log 10 scale';
view(90,0)
daspect([1 1 1])
xlabel('X-axis [km]')
ylabel('Y-axis [km]')
zlabel('Z-axis [km]')
title_perp = ['Mg sputtering in perpendicular plane at orbit angle ',is];
title({title_perp,''})
For those who want a working example for trying to fix it, see code below.
% Create data with similar structure as original
x = linspace(-100,100,100);
y = linspace(-100,100,100);
z = linspace(-100,100,100);
[xg,yg,zg] = meshgrid(x,y,z);
density = rand([100,100,100]);
% Plot data
figure
subplot(1,2,1)
h=slice(xg,yg,zg,density,[],[],0);
set(h,'edgecolor','none');
colormap(jet);
c = colorbar;
view(2)
daspect([1 1 1])
subplot(1,2,2)
g=slice(xg,yg,zg,density,0,[],[]);
set(g,'edgecolor','none');
colormap(jet);
c = colorbar;
view(90,0)
daspect([1 1 1])
here's a possible workaround, first get the color data from each slice, then use imagesc or imshowto plot that slice data. Using your example:
h=slice(xg,yg,zg,density,0,[],[]);
H=get(h,'CData');
...
g=slice(xg,yg,zg,density,0,[],[]);
G=get(g,'CData');
...
Then open a new figure and use imagesc or imshow:
figure;
subplot(1,2,1)
imshow(H); colormap(jet); colorbar
subplot(1,2,2)
imshow(G); colormap(jet); colorbar

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 outside axis in Matlab

How to plot something outside the axis with MATLAB? I had like to plot something similar to this figure;
Thank you.
Here is one possible trick by using two axes:
%# plot data as usual
x = randn(1000,1);
[count bin] = hist(x,50);
figure, bar(bin,count,'hist')
hAx1 = gca;
%# create a second axis as copy of first (without its content),
%# reduce its size, and set limits accordingly
hAx2 = copyobj(hAx1,gcf);
set(hAx2, 'Position',get(hAx1,'Position').*[1 1 1 0.9], ...
'XLimMode','manual', 'YLimMode','manual', ...
'YLim',get(hAx1,'YLim').*[1 0.9])
delete(get(hAx2,'Children'))
%# hide first axis, and adjust Z-order
axis(hAx1,'off')
uistack(hAx1,'top')
%# add title and labels
title(hAx2,'Title')
xlabel(hAx2, 'Frequency'), ylabel(hAx2, 'Mag')
and here is the plot before and after:
You can display one axis with the scale you want, then plot your data on another axis which is invisible and large enough to hold the data you need:
f = figure;
% some fake data
x = 0:20;
y = 23-x;
a_max = 20;
b_max = 23;
a_height = .7;
%% axes you'll see
a = axes('Position', [.1 .1 .8 a_height]);
xlim([0 20]);
ylim([0 20]);
%% axes you'll use
scale = b_max/a_max;
a2 = axes('Position', [.1 .1 .8 scale*a_height]);
p = plot(x, y);
xlim([0 20]);
ylim([0 b_max]);
set(a2, 'Color', 'none', 'Visible', 'off');
I had similar problem and I've solved it thanks to this answer. In case of bar series the code is as follows:
[a,b] = hist(randn(1000,1)); % generate random data and histogram
h = bar(b,a); % plot bar series
ylim([0 70]) % set limits
set(get(h,'children'),'clipping','off')% turn off clippings