I have a 3-dimensional data to be plotted in matlab. The data set are built by stacking 10 exponential curves with different parameters along y directions such as
x = 0:0.01:15;
x0 = 0.5;
y = [beta1, beta2, beta3, beta4, beta5, beta6, beta7, beta8, beta9, beta10];
Z(1, :) = A*exp(-(x-x0).^2/beta1);
Z(2, :) = A*exp(-(x-x0).^2/beta2);
Z(3, :) = A*exp(-(x-x0).^2/beta3);
Z(4, :) = A*exp(-(x-x0).^2/beta4);
...
Z(10, :) = A*exp(-(x-x0).^2/beta10);
% here A could be change based on beta too (no code shown here)
I am trying to plot Z with waterfall except for I don't want the height (i.e. the vertical line) appears on the edge. I don't know if there is any other way to plot the data as waterfall-like curves but without those vertical lines. Thanks
"it is plotted with lines instead of patch with surface".
In other words, you want the boundary lines to be invisible. Well that's no trivial feat as the boundary lines are separate from any color scheme you can directly include. What you need to do is get the data after it drawn then modify it accordingly:
e.g.
[X,Y,Z] = peaks(30);
h = waterfall (X,Y,Z);
CD = get (h, 'CData');
CD(1,:) = nan;
CD(end-2:end,:) = nan;
set (h, 'CData', CD)
note that CD(1,:) is for the "rising" boundary, while CD(end-2:end-1,:) is for the falling boundary, and CD(end,:) is for the bottom.
i know this is an old post, but the below will make the region under the curve transparent:
figure;
[X,Y,Z] = peaks(10);
handle_figure = waterfall( X, Y, Z );
set( handle_figure, 'FaceColor', 'none' );
Related
I've found this answer, but I can't complete my work. I wanted to plot more precisely the functions I am studying, without overcoloring my function with black ink... meaning reducing the number of mesh lines. I precise that the functions are complex.
I tried to add to my already existing code the work written at the link above.
This is what I've done:
r = (0:0.35:15)'; % create a matrix of complex inputs
theta = pi*(-2:0.04:2);
z = r*exp(1i*theta);
w = z.^2;
figure('Name','Graphique complexe','units','normalized','outerposition',[0.08 0.1 0.8 0.55]);
s = surf(real(z),imag(z),imag(w),real(w)); % visualize the complex function using surf
s.EdgeColor = 'none';
x=s.XData;
y=s.YData;
z=s.ZData;
x=x(1,:);
y=y(:,1);
% Divide the lengths by the number of lines needed
xnumlines = 10; % 10 lines
ynumlines = 10; % 10 partitions
xspacing = round(length(x)/xnumlines);
yspacing = round(length(y)/ynumlines);
hold on
for i = 1:yspacing:length(y)
Y1 = y(i)*ones(size(x)); % a constant vector
Z1 = z(i,:);
plot3(x,Y1,Z1,'-k');
end
% Plotting lines in the Y-Z plane
for i = 1:xspacing:length(x)
X2 = x(i)*ones(size(y)); % a constant vector
Z2 = z(:,i);
plot3(X2,y,Z2,'-k');
end
hold off
But the problem is that the mesh is still invisible. How to fix this? Where is the problem?
And maybe, instead of drawing a grid, perhaps it is possible to draw circles and radiuses like originally on the graph?
I found an old script of mine where I did more or less what you're looking for. I adapted it to the radial plot you have here.
There are two tricks in this script:
The surface plot contains all the data, but because there is no mesh drawn, it is hard to see the details in this surface (your data is quite smooth, this is particularly true for a more bumpy surface, so I added some noise to the data to show this off). To improve the visibility, we use interpolation for the color, and add a light source.
The mesh drawn is a subsampled version of the original data. Because the original data is radial, the XData and YData properties are not a rectangular grid, and therefore one cannot just take the first row and column of these arrays. Instead, we use the full matrices, but subsample rows for drawing the circles and subsample columns for drawing the radii.
% create a matrix of complex inputs
% (similar to OP, but with more data points)
r = linspace(0,15,101).';
theta = linspace(-pi,pi,101);
z = r * exp(1i*theta);
w = z.^2;
figure, hold on
% visualize the complex function using surf
% (similar to OP, but with a little bit of noise added to Z)
s = surf(real(z),imag(z),imag(w)+5*rand(size(w)),real(w));
s.EdgeColor = 'none';
s.FaceColor = 'interp';
% get data back from figure
x = s.XData;
y = s.YData;
z = s.ZData;
% draw circles -- loop written to make sure the outer circle is drawn
for ii=size(x,1):-10:1
plot3(x(ii,:),y(ii,:),z(ii,:),'k-');
end
% draw radii
for ii=1:5:size(x,2)
plot3(x(:,ii),y(:,ii),z(:,ii),'k-');
end
% set axis properties for better 3D viewing of data
set(gca,'box','on','projection','perspective')
set(gca,'DataAspectRatio',[1,1,40])
view(-10,26)
% add lighting
h = camlight('left');
lighting gouraud
material dull
How about this approach?
[X,Y,Z] = peaks(500) ;
surf(X,Y,Z) ;
shading interp ;
colorbar
hold on
miss = 10 ; % enter the number of lines you want to miss
plot3(X(1:miss:end,1:miss:end),Y(1:miss:end,1:miss:end),Z(1:miss:end,1:miss:end),'k') ;
plot3(X(1:miss:end,1:miss:end)',Y(1:miss:end,1:miss:end)',Z(1:miss:end,1:miss:end)','k') ;
Question
When using polarhistogram(theta) to plot a dataset containing azimuths from 0-360 degrees. Is it possible to specify colours for given segments?
Example
In the plot bellow for example would it be possible to specify that all bars between 0 and 90 degrees (and thus 180-270 degrees also) are red? whilst the rest remains blue?
Reference material
I think if it exists it will be within here somewhere but I am unable to figure out which part exactly:
https://www.mathworks.com/help/matlab/ref/polaraxes-properties.html
If you use rose, you can extract the edges of the histogram and plot each bar one by one. It's a bit of a hack but it works, looks pretty and does not require Matlab 2016b.
theta = atan2(rand(1e3,1)-0.5,2*(rand(1e3,1)-0.5));
n = 25;
colours = hsv(n);
figure;
rose(theta,n); cla; % Use this to initialise polar axes
[theta,rho] = rose(theta,n); % Get the histogram edges
theta(end+1) = theta(1); % Wrap around for easy interation
rho(end+1) = rho(1);
hold on;
for j = 1:floor(length(theta)/4)
k = #(j) 4*(j-1)+1; % Change of iterator
h = polar(theta(k(j):k(j)+3),rho(k(j):k(j)+3));
set(h,'color',colours(j,:)); % Set the color
[x,y] = pol2cart(theta(k(j):k(j)+3),rho(k(j):k(j)+3));
h = patch(x,y,'');
set(h,'FaceColor',colours(j,:),'FaceAlpha',0.2);
uistack(h,'down');
end
grid on; axis equal;
title('Coloured polar histogram')
Result
I have a 3-dimensional data to be plotted in matlab. The data set are built by stacking 10 exponential curves with different parameters along y directions such as
x = 0:0.01:15;
x0 = 0.5;
y = [beta1, beta2, beta3, beta4, beta5, beta6, beta7, beta8, beta9, beta10];
Z(1, :) = A*exp(-(x-x0).^2/beta1);
Z(2, :) = A*exp(-(x-x0).^2/beta2);
Z(3, :) = A*exp(-(x-x0).^2/beta3);
Z(4, :) = A*exp(-(x-x0).^2/beta4);
...
Z(10, :) = A*exp(-(x-x0).^2/beta10);
% here A could be change based on beta too (no code shown here)
I am trying to plot Z with waterfall except for I don't want the height (i.e. the vertical line) appears on the edge. I don't know if there is any other way to plot the data as waterfall-like curves but without those vertical lines. Thanks
"it is plotted with lines instead of patch with surface".
In other words, you want the boundary lines to be invisible. Well that's no trivial feat as the boundary lines are separate from any color scheme you can directly include. What you need to do is get the data after it drawn then modify it accordingly:
e.g.
[X,Y,Z] = peaks(30);
h = waterfall (X,Y,Z);
CD = get (h, 'CData');
CD(1,:) = nan;
CD(end-2:end,:) = nan;
set (h, 'CData', CD)
note that CD(1,:) is for the "rising" boundary, while CD(end-2:end-1,:) is for the falling boundary, and CD(end,:) is for the bottom.
i know this is an old post, but the below will make the region under the curve transparent:
figure;
[X,Y,Z] = peaks(10);
handle_figure = waterfall( X, Y, Z );
set( handle_figure, 'FaceColor', 'none' );
I need to make a plot with a discrete colorbar in Matlab. I do this in the following way:
data = randi(10, 20);
imagesc(data)
my_colormap = rand(10, 3);
colormap(my_colormap)
cb = colorbar
set(cb,'YTickLabel',{'A';'B';'C';'D';'E';'F';'G';'H';'I';'J';})
Now my problem is that the colorbar tick labels and the small lines in the colorbar don't align nicely. How can I even the colorbar tick labels and the small lines better as illustrated in the following pic:
The TickLabel on the colorbar each correspond to a value (a Tick). To place the TickLabels in the middle, you need to place the tick in the middle. To make this dynamic (so that It does not change when resizing the image) was I bit tricky I recall and I do not really recall. To set the ticks just once is not so hard though,
set(hCbar,'YTicks',RightYTicks);
EDIT:
On request I will post an example. This should give a hint of what to do.
x = 1:10;
y = 1:10;
cmap = jet(10);
[x, y] = meshgrid(x,y); %x and y grid
c = x-0.1; %Set color code to increase to the right
hFig = figure;
scatter(x(:),y(:),10,c(:),'filled'); % Simpler for the example
set(gca(hFig),'CLim',[0,10]);
colormap(cmap);
hCbar = colorbar;
set(hCbar,'YTicks',0.5:9.5);
set(hCbar,'YTickLabels',{'A','B','C','D','E','F','G','H','I','J'});
For newer matlab version, the YTicks may have changed name to Ticks And YTickLabels may be called TickLabels.
I would like to change the default arrow head style in quiver plot. How can I change it?
For Matlab Version > R2014b
Since R2014b version, Matlab has modified the structure of its graphical components. Here is the up-to-date code that uses Matlab's annotations.
is produced by
headWidth = 8;
headLength = 8;
LineLength = 0.08;
%some data
[x,y] = meshgrid(0:0.2:2,0:0.2:2);
u = cos(x).*y;
v = sin(x).*y;
%quiver plots
figure('Position',[10 10 1000 600],'Color','w');
hax_1 = subplot(1,2,1);
hq = quiver(x,y,u,v); %get the handle of quiver
title('Regular Quiver plot','FontSize',16);
%get the data from regular quiver
U = hq.UData;
V = hq.VData;
X = hq.XData;
Y = hq.YData;
%right version (with annotation)
hax_2 = subplot(1,2,2);
%hold on;
for ii = 1:length(X)
for ij = 1:length(X)
headWidth = 5;
ah = annotation('arrow',...
'headStyle','cback1','HeadLength',headLength,'HeadWidth',headWidth);
set(ah,'parent',gca);
set(ah,'position',[X(ii,ij) Y(ii,ij) LineLength*U(ii,ij) LineLength*V(ii,ij)]);
end
end
%axis off;
title('Quiver - annotations ','FontSize',16);
linkaxes([hax_1 hax_2],'xy');
Please note that this piece of code changes the head style and controls for the length of the line (in the left panel, you can see that arrows overlap on the upper-left part of the left subplot, while it does not on the right subplot). The length and width of the arrow heads are not modified.
For this edit, I didn't keep the colors scheme that coded for the angle, and discarded the dynamic head size. It makes things clearer.
For Matlab Version < R2014b
Quiver plots are hard to modify. As #Luis Mendo said, you can modify the quiver function within the matlab install. However, you will still be limited by the complexity of programmatically drawing arrows with nice patches/lines. There might be an easier route using annotation - see the "Quiver - annotation" subplot that sets the headStyle property to cback1.
Annotations are graphical objects (lines, textboxes, arrows, ...) that you can be easily inserted by hand once a plot is done. They display additional text or point to a particular area for example. You can also insert them programmatically by defining their positions - and that's the option we will take. We first draw a regular quiver plot (left panel), get the blue lines' X and Y data, and use these coordinates to insert annotation arrows, each of them being displayed at the exact same location (same position, same angle, same size; right panel).
Annotation arrows have some nice properties you can easily modify, such as Color, HeadWidth, HeadLength, and HeadStyle. In the following plot, I modified each arrow's color depending on its angle against the x-axis, and headWidth that depends length.
The following picture
is produced by
%some data
[x,y] = meshgrid(0:0.2:2,0:0.2:2);
u = cos(x).*y;
v = sin(x).*y;
%quiver plots
figure('Position',[10 10 1000 600],'Color','w');
hax_1 = subplot(1,2,1);
%left version (regular)
hq1 = quiver(x,y,u,v);
%get the line position (first handle)
hkid = get(hq1,'children');
X = get(hkid(1),'XData');
Y = get(hkid(1),'YData');
axis off;
title('Quiver - regular ','FontSize',16);
%right version (with annotation)
hax_2 = subplot(1,2,2);
cmap = jet(116); %colormap, 116 because angles goes up to 115 degrees
for ii = 1:3:length(X)-1
headWidth = 200 * sqrt((X(ii+1)-X(ii)).^2 + (Y(ii+1)-Y(ii)).^2); % set the headWidth, function of length of arrow
angled = floor(atan2(Y(ii+1)-Y(ii),X(ii+1)-X(ii))*180/pi) + 1; %get the angle
ah = annotation('arrow',...
'Color', cmap(angled,:),...
'headStyle','cback1','HeadLength',50,'HeadWidth',headWidth);
set(ah,'parent',gca);
set(ah,'position',[X(ii) Y(ii) X(ii+1)-X(ii) Y(ii+1)-Y(ii)]);
end
axis off;
title('Quiver - annotations ','FontSize',16);
linkaxes([hax_1 hax_2],'xy');
The file refresh.m located in folder ...\MATLAB\...\toolbox\matlab\specgraph\#specgraph\#quivergroup\#quivergroup contains the following lines:
%// Arrow head parameters
alpha = .33; %// Size of arrow head relative to the length of the vector
beta = .25; %// Width of the base of the arrow head relative to the length
Changing the values of alpha and beta achieves the desired effect.
However, this entails modifying Matlab's files, and thus it's not recommended. If you do it, keep a copy of the original refresh.m file.
Results using the example code that appears in quiver's help:
[x,y] = meshgrid(-2:.2:2,-1:.15:1);
z = x .* exp(-x.^2 - y.^2); [px,py] = gradient(z,.2,.15);
quiver(x,y,px,py), hold off, axis image
With original parameters (alpha = .33; beta = .25;):
With alpha = .5; beta = .5;:
You can start here:
http://www.mathworks.com/help/matlab/ref/quiver.html
and then you can look for the available properties of quiver here:
http://www.mathworks.com/help/matlab/ref/quivergroupproperties.html
For example, the property MaxHeadSize allows to change the size of the arrow-heads.
EDIT: More information in this link: Arrow properties
Read at bottom, where says
You can select an annotation and then choose Show M-code to obtain a
code snippet that you can insert in a function or script to reproduce
the annotation.
This answer of pablo1977 was the most instructive for me. I managed to get bigger arrow heads by adjusting the quiver group properties, namely by these 2 lines of code:
h = quiver(...);
set(h,'MaxHeadSize',1e2,'AutoScaleFactor',1);
Check out arrow3() from the MATLAB file-exchange
https://www.mathworks.com/matlabcentral/fileexchange/14056-arrow3
In addition to these examples.
https://kr.mathworks.com/matlabcentral/mlc-downloads/downloads/submissions/14056/versions/16/previews/arrow3_examples.html
It is faster than the annotation command, and produces similar results.
Using the above examples
headWidth =0.8; % 1/10 of annotation
headLength=0.8; % 1/10 of annotation
LineLength = 0.08; % same as annotation
[x,y] = meshgrid(0:0.2:2,0:0.2:2);
u = cos(x).*y;
v = sin(x).*y;
figure();
%hq = quiver(x,y,u,v);
p1 = [x(:) y(:)]; % data start point
u = u(:); v=v(:);
arrow3(p1,p1+LineLength*[u,v],'k',headWidth,headLength);
Sorry I can't post a picture of this plotted, since I need to earn more reputation points. The arrowheads are closed and all similar size, like the annotation command would give.