MATLAB: Color of sphere distorts color scheme values - matlab

I have the following MWE, showing a surf-plot and a sphere,
figure(1)
[xx yy] = meshgrid(0:0.1:pi, 0:0.1:pi);
surf(xx, yy, zeros(size(xx)), 0.001*sin(xx), 'EdgeColor', 'none')
hold on
[xS,yS,zS] = sphere(50);
surf(xS+1, yS+1, zS+1,'FaceColor', 'k', 'edgecolor','none')
hold off
colorbar
The amplitude of the surf-plot is so small that one cannot see what value it has wrt. the colorbar. This is due to the sphere, which has a large amplitude and "distorts" everything.
Is there a way to somehow force the figure to not take into account the color of the sphere? Or maybe change its "amplitude"? I tried changing caxis, but it doesn't make a difference.

Set up manually the limits of your colorbar with caxis
your colors are C=0.001*sin(xx)
then, after the plotting, add caxis([min(C(:)) max(C(:))]) and you will have the limits are you wish

Related

Stabilizing the colormap range to compare two surface plot diagrams in Matlab

Whatever I tried I couldn't stabilize the colors of two diagrams. When the values decrease from 0 - 30 to 0-1 the colormap always adapts to new values. In the figures attached, I need to stabilize the first color scale 0-30, and second legend should by all dark blue as well as the surface.
Disregard the y-values.
Thank you so much for all your help and advices.
The partial code is below.
args = {time,freq,abs(cfs).^2};
surf(args{:},'edgecolor','none');
view(0,90); axis tight;
shading interp; colormap(parula(128));
h = colorbar;
I tried this but didn't work.
set(h,'ylim',[0 100]);
yal=linspace(1,100);
set(h,'ytick',yal);
Try adding this instead:
caxis([0 100]);
https://www.mathworks.com/help/matlab/ref/caxis.html

Colorbar limits not respecting axes clims when displaying an image

Im trying to superimpose a trimesh-plot over a image imshow using hold on. This works fine so far. I'd additionally like to display a colorbar, which works too, but unfortunately it does not adjust to the range specified by caxis, does anyone have an idea how to fix this?
This is an example output: The colourbar should display a range from 1 to z, not from 0 to 60. If we remove imshow everything works fine.
Here my MCVE:
clc;clf;clear
T = [1,2,3;3,1,4]; % triangulation
X = [0,1,1,0]*300; % grid coordinates
Y = [0,0,1,1]*300;
for z = 2:20;
clf;
imshow(imread('board.tif')) % plot image (this is a built in matlab test image)
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
colorbar
drawnow
pause(0.5)
end
This appears to be a bug in how older versions of MATLAB handled the colorbar (it's not present with HG2). The "correct" behavior would be that if you have any objects in the current axes that use scaled values, then the colorbar should respect your clims. It seems that MATLAB is using the first child in the current axes to determine whether to respect your clims or not. imshow does not use scaled CDataMapping so colorbar simply ignores your clims.
It looks like you have three options:
Use imagesc rather than imshow
clf;
imagesc(imread('board.tif'));
axis image
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)
Call imshow after you've created your trisurf object
clf;
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
him = imshow(imread('board.tif'));
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)
Set the CDataMapping property of the image object to 'scaled' (will be ignored when displaying the image since it's RGB but it will allow the colorbar to function properly)
clf;
him = imshow(imread('board.tif'));
set(him, 'CDataMapping', 'scaled')
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)

How to Control Relative Size of Figures with Colorbar in Matlab?

I am trying to line up a plot of a signal with an image where the image has a colorbar. The colorbar causes the axes to be offset horizontally.
My intuitive approach would be to fix the size of figures to something, like in Gnuplot with papersize. However, not sure which would be the best fit here.
To Adjust Scaling to Square in Full Screen Mode of Matlab?
I want to maintain the relations between the two figures. I cannot use squareform in the first figure for some reason, while I can in the latter figure.
Code
figure
ax2=subplot(2,2,2);
plot(mat2gray(pdist(data, 'correlation')));
title('Corr pdist');
cbar2 = colorbar(ax2);
xlim([0 size(mat2gray(pdist(data, 'correlation')),2)]);
set(cbar2, 'Visible', 'off');
ax4=subplot(2,2,4);
imshow(squareform( mat2gray(pdist(data, 'correlation')), 'tomatrix') );
colormap('parula'); colorbar;
title('Square Corr pdist');
Wrong Scaling in Output when Full Screen Mode of Matlab where you see the colorbar method is not sufficient for holding relations as proposed in the answer here about How to Control Relative Size of Figures with Colorbar in Matlab?
Right Scaling in Output when Default View
How can you maintain the square view of figures in the Full Screen Mode of Matlab?
I would simply create a colorbar for the top axes as well and set the visibility to off.
figure;
ax1 = subplot(2,1,1);
ax2 = subplot(2,1,2);
cbar1 = colorbar(ax1);
cbar2 = colorbar(ax2);
set(cbar1, 'Visible', 'off')
The benefit here is that you will get consistent behavior when resizing the figures, etc. because the size and position of the two axes will be rendered in the same way.
The other thing you will need to remember is to keep the axes the same in all aspects. So for example if you have an image in the bottom axes (using imshow), MATLAB by default sets the axes to a square. To get your top plot to also be square you will need to use axis square. Then they will continue to line up.
axis(ax1, 'square')

Matlab: How can I control the color of a streamtube plot?

I am currently trying to plot 3D streamtubes. I want the tubes to be colored corresponding to their respective velocity (e.g. slow = blue, fast = red).
To be more exact, I have three 3D-matrices containing the velocity in x, y and z direction. The color of the streamtubes should be sqrt(vx^2+vy^2+vz^2). When using streamtube(x,y,z,vx,vy,vz,sx,sy,sz) the tubes are colored according to their z-coordinate which is useless because it's a 3D plot anyway.
Well this wasn't easy (it ought to be a builtin option), but by modifying the CData of each tube (they are each their own graphics object), you can achieve the desired result. Here's an example
load wind
[sx,sy,sz] = meshgrid(80,20:10:50,0:5:15);
h=streamtube(x,y,z,u,v,w,sx,sy,sz);
drawnow
view(3)
axis tight
shading interp;
This gives this picture:
but then doing this:
vel=sqrt(u.^2+v.^2+w.^2); %// calculate velocities
for i=1:length(h)
%// Modify the colour data of each tube
set(h(i),'CData',interp3(x,y,z,vel,get(h(i),'XData')...
,get(h(i),'YData'),get(h(i),'ZData'),'spline'))
end
drawnow
view(3)
axis tight
shading interp;
gives this result
NOTES:
1) I don't know if this is fully correct, I don't know how to test it
2) You have to interpolate the velocity data from the points where it's known onto the vertices of the streamtubes
3) I found the spline interpolation option to work best, but the other options might work better in other cases

How can I make a "color map" plot in matlab?

I have some data (a function of two parameters) stored in a matlab format, and I'd like to use matlab to plot it. Once I read the data in, I use mesh() to make a plot. My mesh() plot gives me the the value of the function as a color and a surface height, like this:
What matlab plotting function should I use to make a 2D mesh plot where the dependent variable is represented as only a color? I'm looking for something like pm3d map in gnuplot.
By default mesh will color surface values based on the (default) jet colormap (i.e. hot is higher). You can additionally use surf for filled surface patches and set the 'EdgeColor' property to 'None' (so the patch edges are non-visible).
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
% surface in 3D
figure;
surf(Z,'EdgeColor','None');
2D map: You can get a 2D map by switching the view property of the figure
% 2D map using view
figure;
surf(Z,'EdgeColor','None');
view(2);
... or treating the values in Z as a matrix, viewing it as a scaled image using imagesc and selecting an appropriate colormap.
% using imagesc to view just Z
figure;
imagesc(Z);
colormap jet;
The color pallet of the map is controlled by colormap(map), where map can be custom or any of the built-in colormaps provided by MATLAB:
Update/Refining the map: Several design options on the map (resolution, smoothing, axis etc.) can be controlled by the regular MATLAB options. As #Floris points out, here is a smoothed, equal-axis, no-axis labels maps, adapted to this example:
figure;
surf(X, Y, Z,'EdgeColor', 'None', 'facecolor', 'interp');
view(2);
axis equal;
axis off;
gevang's answer is great. There's another way as well to do this directly by using pcolor. Code:
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
figure;
subplot(1,3,1);
pcolor(X,Y,Z);
subplot(1,3,2);
pcolor(X,Y,Z); shading flat;
subplot(1,3,3);
pcolor(X,Y,Z); shading interp;
Output:
Also, pcolor is flat too, as show here (pcolor is the 2d base; the 3d figure above it is generated using mesh):
Note that both pcolor and "surf + view(2)" do not show the last row and the last column of your 2D data.
On the other hand, using imagesc, you have to be careful with the axes. The surf and the imagesc examples in gevang's answer only (almost -- apart from the last row and column) correspond to each other because the 2D sinc function is symmetric.
To illustrate these 2 points, I produced the figure below with the following code:
[x, y] = meshgrid(1:10,1:5);
z = x.^3 + y.^3;
subplot(3,1,1)
imagesc(flipud(z)), axis equal tight, colorbar
set(gca, 'YTick', 1:5, 'YTickLabel', 5:-1:1);
title('imagesc')
subplot(3,1,2)
surf(x,y,z,'EdgeColor','None'), view(2), axis equal tight, colorbar
title('surf with view(2)')
subplot(3,1,3)
imagesc(flipud(z)), axis equal tight, colorbar
axis([0.5 9.5 1.5 5.5])
set(gca, 'YTick', 1:5, 'YTickLabel', 5:-1:1);
title('imagesc cropped')
colormap jet
As you can see the 10th row and 5th column are missing in the surf plot. (You can also see this in images in the other answers.)
Note how you can use the "set(gca, 'YTick'..." (and Xtick) command to set the x and y tick labels properly if x and y are not 1:1:N.
Also note that imagesc only makes sense if your z data correspond to xs and ys are (each) equally spaced. If not you can use surf (and possibly duplicate the last column and row and one more "(end,end)" value -- although that's a kind of a dirty approach).
I also suggest using contourf(Z). For my problem, I wanted to visualize a 3D histogram in 2D, but the contours were too smooth to represent a top view of histogram bars.
So in my case, I prefer to use jucestain's answer. The default shading faceted of pcolor() is more suitable.
However, pcolor() does not use the last row and column of the plotted matrix. For this, I used the padarray() function:
pcolor(padarray(Z,[1 1],0,'post'))
Sorry if that is not really related to the original post