How to do 3D plot using both contourf and surf plot?
조회 수: 17 (최근 30일)
이전 댓글 표시
Hello matlab community,
I have two datasets ( Z = index and data=observation data) , both are 2D matrix and have different max/min.Both are defined at same X and Y location (this two also 2D matrix).
I want to show both this data in a 3d plot using surf and contourf command.
I have tried with the given code below and have shown you a plot that I am getting.I want to show both this data in a 3d plot using surf and contourf command.I want to plot a surface plot (to show 3d distribution) of the given "data" at the top of the index (Z data). That is 3d distribution of "data" and at z=0 I want to show the index data (Z data). So at xy plane (at z=0) of 3d distribution of "data", I want to plot the contourf of Index data.
I have tried with the code and have sown you a plot that I am getting (1st figure). You can see two plots are there in the figure i just want "pink and blue contourf" plot at z=0 of the other plot. (don't need to show xticks,zticks,yticks of contourf as both X,Y are same for two figure). I want a figure like the attached screenshot. I have also attached the data for better clarity of my question.
f=figure('color','w');
ax1 = axes;
surf(ax1,X(1:skip:end,1:skip:end,i),Y(1:skip:end,1:skip:end,i),data(1:skip:end,1:skip:end),data(1:skip:end,1:skip:end),'FaceAlpha',0.9, 'FaceColor','flat','EdgeColor','none');
xlim([0,76])
view(2)
colormap(ax1,'jet')
view(-15,50)
%shading interp
hold on
ax2 = axes;
contourf(ax2,X(1:skip:end,1:skip:end,i),Y(1:skip:end,1:skip:end,i),squeeze(Z(1:skip:end,1:skip:end,i)),'EdgeColor','none')
colormap(ax2,flipud(rgb))
xlim([0,76])
zticks([])
view(-15,150)
%linkaxes([ax1,ax2]);
axis equal
% Link two axes together
hLink = linkprop([ax1,ax2],{'XLim','YLim','ZLim','CameraUpVector','CameraPosition','CameraTarget'});
Any help would be appreciated and many thanks in advance.
댓글 수: 0
채택된 답변
Voss
2022년 3월 1일
It may be convenient to put both the surface and the contour in the same axes. Of course an axes can only have one colormap, so, since in this case you want to have different "colormaps" for each one, it is necessary to determine the colors of the surface explicitly (by indexing into the jet() colormap), then use the other colormap for the contour (I don't know what rgb is, so I used the 'cool' colormap to illustrate - you can use your rgb colormap there).
Your resulting code might look like this:
% loading data and making up variables
load('X.mat');
load('Y.mat');
load('Z.mat');
load('data.mat');
data = r;
skip = 1;
i = 1;
% get the jet colormap because we need to use its colors to set the
% surface's CData directly
cmap = jet();
% use the values of "data" to determine the corresponding indices into
% cmap:
min_data = min(min(data(1:skip:end,1:skip:end)));
max_data = max(max(data(1:skip:end,1:skip:end)));
% data == min_data -> index = 1 (i.e., first color in cmap)
% data == max_data -> index = size(cmap,1) (i.e., last color in cmap)
cmap_idx = round((data(1:skip:end,1:skip:end)-min_data)/(max_data-min_data)*(size(cmap,1)-1)+1);
% now handle NaNs because they can't be used as indices:
% make note of where cmap_idx is NaN:
nan_cdata = isnan(cmap_idx);
% set cmap_idx to 1 there (just has to be a valid index, doesn't matter
% what it is):
cmap_idx(nan_cdata) = 1;
% perform the indexing into cmap:
cdata = cmap(cmap_idx,:);
% now cdata is a matrix of RGB colors
% set cdata to NaN at the locations where the data was NaN:
cdata(nan_cdata,:) = NaN;
% finally reshape cdata to make it n-by-m-by-3:
cdata = reshape(cdata,[size(data(1:skip:end,1:skip:end)) 3]);
% begin plotting
f=figure('color','w');
ax1 = axes;
% make the surface, using cdata as the color matrix
surf(ax1,X(1:skip:end,1:skip:end,i),Y(1:skip:end,1:skip:end,i),data(1:skip:end,1:skip:end),cdata,'FaceAlpha',0.9, 'FaceColor','flat','EdgeColor','none');
% make the contour
hold on
contourf(ax1,X(1:skip:end,1:skip:end,i),Y(1:skip:end,1:skip:end,i),squeeze(Z(1:skip:end,1:skip:end,i)),'EdgeColor','none')
% set up the colormap for the contour
colormap(ax1,flipud(cool()));%flipud(rgb))
% set the view, etc.
xlim([0,76])
zticks([])
view(-15,150)
axis equal
댓글 수: 2
Voss
2022년 3월 2일
With both the surface and the contour in a single axes, you can only have one proper colorbar.
But you can make your own "colorbar" by creating another axes and a surface in that axes showing the colors. See the last part of this code for how you might do that:
% loading data and making up variables
load('X.mat');
load('Y.mat');
load('Z.mat');
load('data.mat');
data = r;
skip = 1;
i = 1;
% get the jet colormap because we need to use its colors to set the
% surface's CData directly
cmap = jet();
% use the values of "data" to determine the corresponding indices into
% cmap:
min_data = min(min(data(1:skip:end,1:skip:end)));
max_data = max(max(data(1:skip:end,1:skip:end)));
% data == min_data -> index = 1 (i.e., first color in cmap)
% data == max_data -> index = size(cmap,1) (i.e., last color in cmap)
cmap_idx = round((data(1:skip:end,1:skip:end)-min_data)/(max_data-min_data)*(size(cmap,1)-1)+1);
% now handle NaNs because they can't be used as indices:
% make note of where cmap_idx is NaN:
nan_cdata = isnan(cmap_idx);
% set cmap_idx to 1 there (just has to be a valid index, doesn't matter
% what it is):
cmap_idx(nan_cdata) = 1;
% perform the indexing into cmap:
cdata = cmap(cmap_idx,:);
% now cdata is a matrix of RGB colors
% set cdata to NaN at the locations where the data was NaN:
cdata(nan_cdata,:) = NaN;
% finally reshape cdata to make it n-by-m-by-3:
cdata = reshape(cdata,[size(data(1:skip:end,1:skip:end)) 3]);
% begin plotting
f=figure('color','w');
ax1 = axes;
% make the surface, using cdata as the color matrix
surf(ax1,X(1:skip:end,1:skip:end,i),Y(1:skip:end,1:skip:end,i),data(1:skip:end,1:skip:end),cdata,'FaceAlpha',0.9, 'FaceColor','flat','EdgeColor','none');
% make the contour
hold on
contourf(ax1,X(1:skip:end,1:skip:end,i),Y(1:skip:end,1:skip:end,i),squeeze(Z(1:skip:end,1:skip:end,i)),'EdgeColor','none')
% set up the colormap for the contour
colormap(ax1,flipud(cool()));%flipud(rgb))
% set the view, etc.
xlim([0,76])
zticks([])
view(-15,150)
axis equal
% create colorbar for the contour:
cb_contour = colorbar();
% make another colorbar for the surface
% it's going to be 50 pixels to the right of the first colorbar
% (adjust it at will)
cb_units = get(cb_contour,'Units');
set(cb_contour,'Units','pixels');
cb_pos = get(cb_contour,'Position');
set(cb_contour,'Units',cb_units);
% 2nd colorbar axes:
cb_surface_axes = axes( ...
'Parent',gcf(), ...
'Units','pixels', ...
'Position',cb_pos+[50 0 0 0], ...
'Box','on', ...
'XTick',[], ...
'YAxisLocation','right', ...
'YLim',[min_data max_data]);
% 2nd colorbar colors (a surface):
N_colors = size(cmap,1);
cb_surface_surface = surface( ...
'Parent',cb_surface_axes, ...
'XData',[0 1], ...
'YData',linspace(min_data,max_data,N_colors), ...
'ZData',zeros(N_colors,2), ...
'CData',reshape(repmat(cmap,2,1),N_colors,2,3), ...
'EdgeColor','none');
추가 답변 (1개)
ONKAR
2023년 6월 1일
Obtain the 3 dimensional plot for following function using matlab z=(sin(underroot(x^2+y^2)))/(underroot(x^2+y^2)),-6<=x<=6, -6<=y<=6.
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Orange에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!