Filled contour plot on other planes (X-Z or Y-Z)

39 views (last 30 days)
Hello I was looking for a nice way to visualize my 3D data.
Firstly, I did it using slices of pcolor plots in different place.
However, it's hard to interpret values like this
So I was trying to repeat this plot with contourf but it only allows plotting in X-Y plane.
Is any possibility to create filled contours in other planes?
I found only the contourslice function for contours.

Accepted Answer

Benjamin Kraus
Benjamin Kraus on 13 Feb 2023
contourf works fine when used with an hgtransform, except it is not updating the automatically selected limits correctly, so you will need to update the limits to make sure your rotated contour object is visible in the axes.
I'm not quite sure why you are getting the error "The new value for the Matrix property may cause rendering problems.", but I suspect it has nothing to do with contour, but rather the specific Matrix you are using is not well defined. If you can provide the specific matrix that you used that produced that error message, that would be helpful to get a better idea of why you get that error message.
Considering the example code you provided one of your comments, with some small modifications:
% Default Matrix (eye(4)) works fine, as expected:
fig = figure;
ax = axes('Parent',fig);
t = hgtransform('Parent',ax);
Z = peaks;
contourf(Z,32,':','Parent',t);
% Rotating 90 degrees around X moves the contour into the X/Z plane, and
% requires updating the limits and view.
fig = figure;
ax = axes('Parent',fig);
t = hgtransform('Parent',ax);
Z = peaks;
contourf(Z,32,':','Parent',t);
t.Matrix = makehgtform('xrotate',pi/2);
ylim([-1 1])
zlim([1 49]);
view(0,0)
% The contour starts out at z = 0, x = [1 49], and y = [1 49]. If you
% rotate 45 degrees around the X-axis, the new location is:
% x = [1 49]
% y = sqrt(2)/2.*[1 49]
% z = sqrt(2)/2.*[1 49]
beforeX = [1 49];
beforeY = [1 49];
beforeZ = [0 0];
beforeLim = [beforeX; beforeY; beforeZ; [0 0]];
transformationMatrix = makehgtform('xrotate',pi/4);
afterLim = transformationMatrix*beforeLim;
afterX = afterLim(1,:);
afterY = afterLim(2,:);
afterZ = afterLim(3,:);
fig = figure;
ax = axes('Parent',fig);
t = hgtransform('Parent',ax);
Z = peaks;
contourf(Z,32,':','Parent',t);
t.Matrix = transformationMatrix;
xlim(afterX)
ylim(afterY)
zlim(afterZ)
% The contour starts out at z = 0, x = [1 49], and y = [1 49]. If you
% rotate 2 degrees (pi/90) around the Y-axis ([0 1 0]), the new location is:
% x = ~[1 49]
% y = ~[1 49]
% z = ~[-1.7 -0.03]
beforeX = [1 49];
beforeY = [1 49];
beforeZ = [0 0];
beforeLim = [beforeX; beforeY; beforeZ; [0 0]];
transformationMatrix = makehgtform('axisrotate',[0 1 0],pi/90);
afterLim = transformationMatrix*beforeLim;
afterX = sort(afterLim(1,:));
afterY = sort(afterLim(2,:));
afterZ = sort(afterLim(3,:));
fig = figure;
ax = axes('Parent',fig);
t = hgtransform('Parent',ax);
Z = peaks;
contourf(Z,32,':','Parent',t);
t.Matrix = transformationMatrix;
xlim(afterX)
ylim(afterY)
zlim(afterZ)
% Note that makehgtform('axisrotate',[0 1 0],pi/90) is equivalent to
% makehgtform('yrotate',pi/90), so you will get the same answer.
mat1 = makehgtform('axisrotate',[0 1 0],pi/90)
mat1 = 4×4
0.9994 0 0.0349 0 0 1.0000 0 0 -0.0349 0 0.9994 0 0 0 0 1.0000
mat2 = makehgtform('yrotate',pi/90)
mat2 = 4×4
0.9994 0 0.0349 0 0 1.0000 0 0 -0.0349 0 0.9994 0 0 0 0 1.0000
isequal(mat1, mat2)
ans = logical
1
  13 Comments
Volodymyr Rodin
Volodymyr Rodin on 15 Feb 2023
@Benjamin Kraus Here is an example with peaks
figure1 = figure(1);
axes1 = axes('Parent',figure1);
hold(axes1,'on');
Z=peaks(49);
[~,ix]=contourf(Z,32,':','Parent',axes1)
ix =
Contour with properties: EdgeColor: [0 0 0] LineStyle: ':' LineWidth: 0.5000 FaceColor: 'flat' LevelList: [-6.5466 -6.1036 -5.6605 -5.2174 -4.7743 -4.3312 -3.8881 -3.4450 -3.0020 -2.5589 -2.1158 -1.6727 -1.2296 -0.7865 -0.3434 0.0996 0.5427 0.9858 1.4289 1.8720 2.3151 2.7581 3.2012 3.6443 4.0874 4.5305 4.9736 5.4167 5.8597 6.3028 6.7459 … ] XData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] YData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] ZData: [49×49 double] Show all properties
ix.ZLocation=7;
xlim([0 49])
ylim([0 49])
zlim([0 49])
set(axes1,'ColorScale','linear','ZMinorTick','on','ZScale','linear');
view(axes1,[50 40]);
axis('square')
t = hgtransform('Parent',axes1);
[~,ix2]=contourf(Z,32,':','Parent',t )
ix2 =
Contour with properties: EdgeColor: [0 0 0] LineStyle: ':' LineWidth: 0.5000 FaceColor: 'flat' LevelList: [-6.5466 -6.1036 -5.6605 -5.2174 -4.7743 -4.3312 -3.8881 -3.4450 -3.0020 -2.5589 -2.1158 -1.6727 -1.2296 -0.7865 -0.3434 0.0996 0.5427 0.9858 1.4289 1.8720 2.3151 2.7581 3.2012 3.6443 4.0874 4.5305 4.9736 5.4167 5.8597 6.3028 6.7459 … ] XData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] YData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] ZData: [49×49 double] Show all properties
ix2.ZLocation=9;
t.Matrix=makehgtform('yrotate',-pi/2)*makehgtform('translate',[0 0 -18]);
t2 = hgtransform('Parent',axes1);
[~,ix3]=contourf(Z,32,':','Parent',t2)
ix3 =
Contour with properties: EdgeColor: [0 0 0] LineStyle: ':' LineWidth: 0.5000 FaceColor: 'flat' LevelList: [-6.5466 -6.1036 -5.6605 -5.2174 -4.7743 -4.3312 -3.8881 -3.4450 -3.0020 -2.5589 -2.1158 -1.6727 -1.2296 -0.7865 -0.3434 0.0996 0.5427 0.9858 1.4289 1.8720 2.3151 2.7581 3.2012 3.6443 4.0874 4.5305 4.9736 5.4167 5.8597 6.3028 6.7459 … ] XData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] YData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] ZData: [49×49 double] Show all properties
ix3.ZLocation=27;
t2.Matrix=makehgtform('xrotate',pi/2)*makehgtform('translate',[0 0 -27*2]);
% ix3.FaceAlpha=0.99
Benjamin Kraus
Benjamin Kraus on 15 Feb 2023
Edited: Benjamin Kraus on 15 Feb 2023
Thanks. This does seem to be a bug. I've reported the bug to the developers. In the meantime, if setting FaceAlpha to 0.99 works, I would continue doing that.
If I had to guess, when you set FaceAlpha to anything close to 1, there is an optimization that is being done for performance reasons that skips some transparency calculations, and the bug is in that pathway. When you set the FaceAlpha to <0.99, it will likely take longer to render, because it is doing extra transparency calculations, but it results in a more accurate picture.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 10 Feb 2023
Create a hgtransform() and parent it to the axes. Extract a 2d slice of the volume (interpn() or even just array access and squeeze()) and contoutf() that, parenting it to the hgtransform (pass in the transform handle where you would pass in an axes). Now set the Matrix property of the transform to rotate it to the desired plane. makehgtform is very useful for creating the matrix.
Note that the rightmost transform in makehgtform is one executed first.
  6 Comments
Volodymyr Rodin
Volodymyr Rodin on 10 Feb 2023
Hi, here is the simple example with peaks. And there is something goes really stramge, you can compare it with the commented part
figure1 = figure(1);
% Create axes
axes1 = axes('Parent',figure1);
hold(axes1,'on');
view(axes1,[-45 45]);
t = hgtransform('Parent',axes1);
Works = eye(4);
Fails1 = makehgtform('xrotate',pi/2);
Fails2 = makehgtform('xrotate',pi/4);
Fails3 = makehgtform('axisrotate',[0 1 0],pi/90); %doing strange rotation
Fails4 = makehgtform('yrotate',pi/90); %doing strange rotation
Z = peaks;
[~,ix]=contourf(Z,32,':','Parent',t)
ix =
Contour with properties: EdgeColor: [0 0 0] LineStyle: ':' LineWidth: 0.5000 FaceColor: 'flat' LevelList: [-6.5466 -6.1036 -5.6605 -5.2174 -4.7743 -4.3312 -3.8881 -3.4450 -3.0020 -2.5589 -2.1158 -1.6727 -1.2296 -0.7865 -0.3434 0.0996 0.5427 0.9858 1.4289 1.8720 2.3151 2.7581 3.2012 3.6443 4.0874 4.5305 4.9736 5.4167 5.8597 6.3028 6.7459 … ] XData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] YData: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49] ZData: [49×49 double] Show all properties
% ix=pcolor(Z,'Parent',t)
set(t,'Matrix',Fails1);
% set(ix,'Parent',t)

Sign in to comment.

Categories

Find more on Contour Plots in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!