I am working on a project which plots deltaL on the y axis and Fnet on the x axis. The script is as follows:
%Variables for delta L
L=518;
E=1040000000;
A=0.0020268;
%Variables for Form Drag
Ad=25.437;
Cd=2.015;
p=999.835;
v=2.02917;
%Array for theta
theta=0:pi/360:pi/45;
Fd=0.5*p*Cd*v^2;
T=(L/2).*tan(theta);
Fnet=sqrt((T.^2)+(Fd.^2));
deltaL=(Fnet.*L)./(E.*A);
plot(Fnet,deltaL,'.');
When I plot the data, the values on the x axis are all the same and the values on the y axis are also the same. The x and y values are different. However, my graph still creates a working model of my data. Is there a piece of my code which is causing this issue or is there some glitch in matlab that can somehow be fixed?
That is because the precision of the values of x/y axis is not high enough.
You can use the trick from this page: http://www.mathworks.fr/support/solutions/en/data/1-3P8CU0/index.html?product=ML&solution=1-3P8CU0
old_ticks = get(gca, 'ytick')';
new_tick_labels = cellfun(#(x) sprintf('%9.6f',x), num2cell(old_ticks), 'uniformoutput', false);
set(gca, 'yticklabel', new_tick_labels)
old_ticks = get(gca, 'xtick')';
new_tick_labels = cellfun(#(x) sprintf('%9.6f',x), num2cell(old_ticks), 'uniformoutput', false);
set(gca, 'xticklabel', new_tick_labels)
result (right-click + "display image" for a better resolution):
You are trying to plot values that increase in very small magnitudes vs their initial value. For example if you would instead plot
plot(Fnet-Fnet(1),deltaL-deltaL(1),'.');
you'll see the relevant numbers that these change by.
A possible solution is to edit the xtick-labels and ytick-labels according to your needs. For Example
plot(Fnet,deltaL,'.');
yt=get(gca,'YTick')'
set(gca,'YTick',yt,'YTickLabel',num2str(yt,'%.6f'));
Actually, you can do it in a single line! just add:
set(gca,'YTick',get(gca,'YTick')','YTickLabel',num2str(get(gca,'YTick')','%.6f'));
Well, the values on the X and Y are not the same - it is just that Matlab rounds the numbers before displaying to 4 or 5 digits (Which is intended and meaningful behavior). You would need to choose a appropriate data presentation (e.g. use an offset for the X and Y data).
For example
xofs = round(mean(Fnet)*100)/100;
yofs = round(mean(deltaL)*10000)/10000;
plot( Fnet-xofs, deltaL-yofs );
xlabel( sprintf('Fnet - %0.2f', xofs) );
ylabel( sprintf('\\DeltaL - %0.4f', yofs) );
Related
I want to represent data with 2 variables in 2D format. The value is represented by color and the 2 variables as the 2 axis. I am using the contourf function to plot my data:
clc; clear;
load('dataM.mat')
cMap=jet(256); %set the colomap using the "jet" scale
F2=figure(1);
[c,h]=contourf(xrow,ycol,BDmatrix,50);
set(h, 'edgecolor','none');
xlim([0.0352 0.3872]);
ylim([0.0352 0.3872]);
colormap(cMap);
cb=colorbar;
caxis([0.7 0.96]);
% box on;
hold on;
Both xrow and ycol are 6x6 matrices representing the coordinates. BDmatrix is the 6x6 matrix representing the corresponding data. However, what I get is this:
The following is the xrow and yrow matices:
The following is the BDmatrix matices:
Would it be possible for the contour color to vary smoothly rather than appearing as straight lines joining the data points? The problem of this figure is the coarse-granularity which is not appealing. I have tried to replace contourf with imagec but it seems not working. I am using MATLAB R2015b.
You can interpolate your data.
newpoints = 100;
[xq,yq] = meshgrid(...
linspace(min(min(xrow,[],2)),max(max(xrow,[],2)),newpoints ),...
linspace(min(min(ycol,[],1)),max(max(ycol,[],1)),newpoints )...
);
BDmatrixq = interp2(xrow,ycol,BDmatrix,xq,yq,'cubic');
[c,h]=contourf(xq,yq,BDmatrixq);
Choose the "smoothness" of the new plot via the parameter newpoints.
To reduce the Color edges, you can increase the number of value-steps. By default this is 10. The following code increases the number of value-steps to 50:
[c,h]=contourf(xq,yq,BDmatrixq,50);
A 3D-surf plot would be more suitable for very smooth color-shading. Just rotate it to a top-down view. The surf plot is also much faster than the contour plot with a lot of value-steps.
f = figure;
ax = axes('Parent',f);
h = surf(xq,yq,BDmatrixq,'Parent',ax);
set(h, 'edgecolor','none');
view(ax,[0,90]);
colormap(Jet);
colorbar;
Note 1: Cubic interpolation is not shape-preserving. That means, the interpolated shape can have maxima which are greater than the maximum values of the original BDmatrix (and minima which are less). If BDmatrix has noisy values, the interpolation might be bad.
Note 2: If you generated xrow and yrow by yourself (and know the limits), than you do not need that min-max-extraction what I did.
Note 3: After adding screenshots of your data matrices to your original posting, one can see, that xrow and ycol come from an ndgrid generator. So we also must use this here in order to be consistent. Since interp2 needs meshgrid we have to switch to griddedInterpolant:
[xq,yq] = ndgrid(...
linspace(min(min(xrow,[],1)),max(max(xrow,[],1)),newpoints ),...
linspace(min(min(ycol,[],2)),max(max(ycol,[],2)),newpoints )...
);
F = griddedInterpolant(xrow,ycol,BDmatrix,'cubic');
BDmatrixq = F(xq,yq);
Environment: Windows 7 64 bit, Matlab 2014a
Objective:
To draw a heatmap of errors for two parameters to be optimized.
To put proper tick marks and tick values
Draw the grid lines in the correct place
Problem: Arranging the X and Y tick positions and values. When the last ("end") value of the vectors in x and y axes are the same, the code I use puts the ticks and values properly. However, when the end values are different it does not, and produces something really weird.
Below I have included the code which I have modified so that you can run it without the need of adding anything. Of course in my case the error vector are the error values, not random numbers. To see the problem of "end value" use the second b vector.
fontsize = 20
k = [2^-5, 2^-3, 2^-1, 2^0, 2^1, 2^3, 2^5, 2^7, 2^9, 2^11, 2^13, 2^15]
b = [2^-5, 2^-3, 2^-1, 2^0, 2^1, 2^3, 2^5, 2^7, 2^8, 2^9, 2^10, 2^11, 2^13, 2^15]
% b = [2^-5, 2^-3, 2^-1, 2^0, 2^1, 2^3, 2^5, 2^7, 2^8, 2^9, 2^10, 2^11, 2^13, 2^19]
errorVector = randi(20, 1, length(b)*length(k))'
figure
% Create a matrix from error vector (size of error vector is [length(k)*length(b),1])
B = reshape(errorVector, [length(b), length(k)])
B = flipud(B)
% imagesc(x,y,C)
imagesc(b, k, B)
title('Heatmap Parameters Percent Error', 'FontSize', fontsize);
% Set colorbar limits
caxis([0 15])
colorbar;
ax1 = gca;
xTickLabel = (k)'
xTick = linspace(k(1), k(end), numel(xTickLabel))';
set(ax1, 'XTick', xTick, 'XTickLabel', xTickLabel)
xlabel('k parameter', 'FontSize', fontsize)
yTickLabel = (b)'
yTick = linspace(b(1), b(end), numel(yTickLabel))';
set(ax1, 'YTick', yTick, 'YTickLabel', flipud(yTickLabel(:)))
ylabel('b parameter', 'FontSize', fontsize)
set(ax1,'FontSize', fontsize)
Here, change any of the end values of b or k vectors, and the program will output a graph where the X and Y ticks are totally wrong.
Also, I would like to draw grid lines. When I use "grid on" it draws grid lines right on the tick marks which is not correct in the case of heatmap. Because tick marks will be in the center of the columns -or rows- but the grid lines should be at the boundaries between the columns -or rows.
By the way if you know a better way to plot a heatmap in Matlab, please do tell.
Please help me solve this problem. Any help is appreciated,
Ilyas
First of all - you don't need to flipud the B matrix - by default imagesc plots the y-data inversed, but you can fix this with the following statement:
set(gca,'ydir','normal');
This also means you don't have to mess around with flipping the tick-labels. You can get the labels right by doing the following:
% replace the imagesc call with:
imagesc(B);
set(gca,'ydir','normal');
% formatting stuff
...
% replace the set commands with:
set(ax1, 'XTick', 1:length(k), 'XTickLabel', k)
set(ax1, 'YTick', 1:length(b), 'YTickLabel', b)
By default, if you don't provide x and y data to the imagesc command, it will number them linearly (1,2,3...). Basically what we've done here is make sure that it has ticks for each of the elements of b and k, and then set the labels to the values of the respective vectors.
Unfortunately, I'm not sure if there is a way to get the grid spacing right with imagesc or not. You could try using pcolor instead, which has it's own set of issues, but allows you to get grid lines (of sorts) between the elements. It also allows you to use an interpolated shading mode, which will make your plot look more like a typical heat map.
To use pcolor instead, you just have to replace imagesc:
% imagesc(B);
% set(gca,'ydir','normal');
pcolor(B);
% this uses a smoother shading method, for a more 'heatmap' like output
% shading interp
Everything else should work as intended, I believe.
I have the graph below I need to create two different x-axis. The unique part of this problem is where the min and max values need to be located. The range for is 0-100 for both, however the 100% value on the second x-axis needs to be where the 50% value is on the first. See the picture for clarification. The red is what I need to add using MATLAB.
I did a lot of looking and while it's very simple to put two different axis on one graph, I couldn't find a solution for this particular problem. I'd like this to be done in the code and not plot tools.
How about this
% dummy data
y = 1:80;
x1 = 100*sin( 4*pi*y/80 ).^2 ;
x2 = 100*cos( 5*pi*y/80).^2;
Plot the first line
figure;
line( x1, y, 'Color', 'b', 'LineWidth', 2 );
Get position and size of first plot
haxes1 = gca;
haxes1_pos = get(haxes1,'Position');
set the 100% of second plot to 50% of first ("tweaking" the width of the axis)
haxes1_pos(3) = haxes1_pos(3)/2;
haxes2 = axes('Position',haxes1_pos,'XAxisLocation','top','Color','none','XColor','r');
Plot the second line
line( x2, y, 'Color', 'k', 'LineWidth',2,'Parent',haxes2);
And this is what you get
I've got 3 vectors
x =[10^(-10) 10^(-9) 10^(-8) 10^(-7) 10^(-6) 10^(-5) 10^(-4) 10^(-3) 10^(-2)]
y =[10^(-10) 10^(-9) 10^(-8) 10^(-7) 10^(-6) 10^(-5) 10^(-4) 10^(-3) 10^(-2)]
and z which is the error that takes values from 5 to 0.01.
I need to create a contour plot. However, I cannot use meshgrid, as the step on my x and y axis should be very small and Matlab crashes when I'm trying that.
Any ideas about resolving it?
You can use meshgrid to produce the required mesh and replace the labels later on. The properties you are looking for are called XTick and XTickLabel. See for example: http://www.mathworks.com/matlabcentral/answers/92565
You need to use a logarithmic scale to see the results in any sensible way. Practically, this means you should probably do
x = logspace(-10, -2, 9);
y = logspace(-10, -2, 9);
logX = log(x);
logY = log(y);
[lxx lyy]=meshgrid(logX, logY);
and then plot contours as usual with
contour(lxx, lyy, reshape(z, [9 9]));
Finally, you would want to annotate your axes to show you are using a log scale - or you can turn off the tick labels and replace them with your own values.
Alternatively, I wonder if you could use the grid you have
[xx yy] = meshgrid(x, y);
and after plotting the contour, doing
set(gca, 'xscale', 'log');
set(gca, 'yscale', 'log');
I can't test this right now, so this may be bad advice. Let me know how it works for you.
I apologize for asking this, I believe this is a simple task, but I don't know how to do it.
Suppose I have a formula y = (exp(-x) + x^2)/sqrt(pi(x) and I want to plot it as y versus x^2.
How does one do this?
Like this:
X = 0:0.1:5; %// Get the x values
x = X.^2; %// Square them
%// Your formula had errors, I fixed them but I could have misinterpreted here, please check
y = (exp(-x) + x.^2)./sqrt(pi*x); %// Calculate y at intervals based on the squared x. This is still y = f(x), I'm just calculating it at the points at which I want to plot it.
plot(x,y) %//Plot against the square X.
At this point this is no different to having just plotted it normally. What you want is to make the tickmarks go up in values of X.^2. This does not change the y-values nor distort the function, it just changes what it looks like visually. Similar to plotting against a log scale:
set(gca, 'XTick', X.^2) %//Set the tickmarks to be squared
The second method gives you a plot like
edit:
Actually I think you were asking for this:
x = 0:0.1:5;
y = x.^2; %// Put your function in here, I'm using a simple quadratic for illustrative purposes.
plot(x.^2,y) %//Plot against the square X. Now your y values a f(x^2) which is wrong, but we'll fix that later
set(gca, 'XTick', (0:0.5:5).^2) %//Set the tickmarks to be a nonlinear intervals
set(gca, 'XTickLabel', 0:0.5:5) %//Cahnge the labels to be the original x values, now accroding to the plot y = f(x) again but has the shape of f(x^2)
So here I'm plotting a simple quadratic, but if I plot it against a squared x it should become linear. However I still want to read off the graph that y=x^2, not y=x, I just want it to look like y=x. So if I read the y value for the x value of 4 on that graph i will get 16 which is still the same correct original y value.
Here's my answer: it is similar to Dan's one, but fundamentally different. You can calculate the values of y as a function of x, but plot them as a function of x^2, which is what the OP was asking, if my understanding is correct:
x = 0:0.1:5; %// Get the x values
x_squared = x.^2; %// Square them
%// Your formula had errors, I fixed them but I could have misinterpreted here, please check
y = (exp(-x) + x.^2)./sqrt(pi*x); %// Calculate y based on x, not the square of x
plot(x_squared,y) %//Plot against the square of x
As Dan mentioned, you can always change the tickmarks:
x_ticks = (0:0.5:5).^2; % coarser vector to avoid excessive number of ticks
set(gca, 'XTick', x_ticks) %//Set the tickmarks to be squared