I would like to know how to plot multiple, 2D contour plots spaced apart in the z-axis, in a 3D figure like this:
With plot3, what you need to do is make the y values for each of your plots z values instead, and if you want to separate the graphs, you need to vary the y values in this 3D plot. Let's do an example. Let's say I want to place 4 graphs on a single plot in that fashion.
Combine plots in the same axes, or create multiple axes in a figure using a tiled chart layout. By default, new plots clear existing plots and reset axes properties, such as the title. However, you can use the hold on command to combine multiple plots in the same axes. For example, plot two lines and a scatter plot.
How plot3 works is that you can either place single vectors in for your x,y,z values, or you can use matrices xMat,yMat,zMat instead. Each column of each matrix of xMat, yMat and zMat denote a single trace to be placed in your plot. Therefore, each column of xMat for each signal goes into a single column.
You can use plot3 to help you facilitate this kind of plotting. With plot3, what you need to do is make the y values for each of your plots z values instead, and if you want to separate the graphs, you need to vary the y values in this 3D plot. Let's do an example.
NOTE: The first part of this answer was meant for HG1 graphics. See the second part if you're working with MATLAB R2014b and up (HG2).
The contour
function internally creates a number of patch
objects, and returns them as a combined hggroup object. So we could set the ZData
of all patches by shifting in the Z-dimensions to the desired level (by default contour is shown at z=0).
Here is an example:
[X,Y,Z] = peaks;
surf(X, Y, Z), hold on % plot surface
[~,h] = contour(X,Y,Z,20); % plot contour at the bottom
set_contour_z_level(h, -9)
[~,h] = contour(X,Y,Z,20); % plot contour at the top
set_contour_z_level(h, +9)
hold off
view(3); axis vis3d; grid on
Here is the code for the set_contour_z_level
function used above:
function set_contour_z_level(h, zlevel)
% check that we got the correct kind of graphics handle
assert(isa(handle(h), 'specgraph.contourgroup'), ...
'Expecting a handle returned by contour/contour3');
assert(isscalar(zlevel));
% handle encapsulates a bunch of child patch objects
% with ZData set to empty matrix
hh = get(h, 'Children');
for i=1:numel(hh)
ZData = get(hh(i), 'XData'); % get matrix shape
ZData(:) = zlevel; % fill it with constant Z value
set(hh(i), 'ZData',ZData); % update patch
end
end
The above solution doesn't work anymore starting with R2014b. In HG2, contour objects no longer have any graphic objects as children (Why Is the Children Property Empty for Some Objects?).
Fortunately there is an easy fix, with a hidden property of contours called ContourZLevel
.
You can learn more undocumented customizations of contours plots here and here.
So the previous example simply becomes:
[X,Y,Z] = peaks;
surf(X, Y, Z), hold on % plot surface
[~,h] = contour(X,Y,Z,20); % plot contour at the bottom
h.ContourZLevel = -9;
[~,h] = contour(X,Y,Z,20); % plot contour at the top
h.ContourZLevel = +9;
hold off
view(3); axis vis3d; grid on
Another solution that works in all versions would be to "parent" the contour to a hgtransform
object, and transform that using a simple z-translation. Something like this:
t = hgtransform('Parent',gca);
[~,h] = contour(X,Y,Z,20, 'Parent',t);
set(t, 'Matrix',makehgtform('translate',[0 0 9]));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With