Plot bar in matlab with log-scale x axis and same width - matlab

I want to plot a bar chart in Matlab with (1) log-scale for x-axis and (2)bars in same width. But with the code below, the width of the bars are different. Can any one help? Many thanks!
xdata = [0.01 0.018 0.032 0.056 0.1 0.18 0.32 0.56 1 1.8 3.2 5.6 10];
ydata = [1.3 1.6 1.5 1.2 1.0 3.5 0.6 3.1 1.6 1.9 1.7 0.3 0.4];
bar(xdata,ydata);
set(gca,'XScale','log');

Instead of plotting xdata on a log scale, plot the log of xdata on a linear scale. Then modify labels to reflect the linear value (not the used log value).
xdata = [0.01 0.018 0.032 0.056 0.1 0.18 0.32 0.56 1 1.8 3.2 5.6 10];
ydata = [1.3 1.6 1.5 1.2 1.0 3.5 0.6 3.1 1.6 1.9 1.7 0.3 0.4];
bar(log10(xdata),ydata);
set(gca,'Xtick',-3:1); %// adjust manually; values in log scale
set(gca,'Xticklabel',10.^get(gca,'Xtick')); %// use labels with linear values

Related

How can I find the average of largest set of non-zero values in an array

How can I find the the starting point of A array and calculate average starting from starting points to 1 second
A=[0 0 0 0 0 -0.01 -0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.01 0.02 0.03 0.04 0.1 0.2 0.3 0.4 0.7 0.8 1 1.2 1.3 1.4 1.5]
Time=[0 0.1 .2 .3 .4 .5 .6 .7 .8 .9 1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.8 3 3.1]
By removing the noise the starting point should be A(17) which is equal to 0.01
Then calculate average of A starting from starting point after 1 seconds
Code is self explanatory
A=[0 0 0 0 0 -0.01 -0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.01 0.02 0.03 0.04 0.1 0.2 0.3 0.4 0.7 0.8 1 1.2 1.3 1.4 1.5] ;
Time=[0 0.1 .2 .3 .4 .5 .6 .7 .8 .9 1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.8 3 3.1];
%make negative values zero
A(A<0)=0;
%get non negative values position and add padding
mask=[0,A>0,0];
%get starting points
startingPoints =strfind(mask,[0 1]);
%get length of continuous values from starting points
temp =diff(find(~mask))-1;
length = temp(temp>0);
%get the index of largest length
[~,index]=max(length);
%get starting point
dataStartingIndex = startingPoints(index)
%starting point value
A(dataStartingIndex)
%get ending point after 1 seconds
dataEndingIndex=find((Time(dataStartingIndex)+1)==Time);
%find average
avg=mean(A(dataStartingIndex:dataEndingIndex))
This really depends on your data. It is a bit unclear but in your example it seems that noise can exceed your 'information value'. So you can't detect it just with a threshold.
Maybe get the position where A is always superior to something like 0.01 :
startpos= (A>0).argmax()
truedata=A[startpos:]
time=T[startpos:]
you can calculate average with the method .mean()

How to calculate the area between two curves

Based on the following code:
clear vars;
close all;
x1 = [0 0 0.01 0.09 0.1 0.11 0.2 0.3 0.35 0.50 0.64 0.8 1]
y1 = [0.05 0.10 0.15 0.20 0.25 0.30 0.38 0.42 0.45 0.48 0.52 0.86 1]
x2 = [0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.9 0.9 1]
y2 = [0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.9 0.9 1]
plot(x1, y1); hold on;
plot(x2, y2);
I need to calculate the area (green area) between the two curves, for example:
How can I calculate it?
This area is the difference of the two curves integral in the specified domain between each intersection (as mentioned by MBo). Hence, you can find the intersections using InterX and then use trapz to do this:
P = InterX([x1;y1],[x2;y2]);
area = 0;
% for each segment
% each segment is between P(1,i) and P(1, i+1)
% So we can find xsegments with idx = find(x < P(1,i+1) && x > P(1,i)) and [P(1,i) x(idx) P(1,i+1)]
% ...
area = area + abs(trapz(xsegment1i,ysegment1i) - trapz(xsegment2i,ysegment2i));
Since one of the curves is a straight line you can rotate then add up the areas from the new x axis.
The line is at 45 degrees. So the rotation matrix is
cos 45 sin 45
-sin 45 cos 45
Multiply each point in the second curve by that matrix. That gives points with the line as the new x axis. Now use area of the triangle (0.5 * width * height) to add up the areas of the fragments.

Smooth data and graph in MATLAB [duplicate]

Using MATLAB, I have a matrix (data) and am plotting using imagesc(data) to produce a heatmap:
data = [1 1 1 1 1 1 1 1 1 1; 1 1.04 1.04 1.04 1.03 1 1.01 1.01 1.03 1.01; 1.36 1.3 1.25 1.2 1.15 1.1 1.2 1.13 1.07 1.11; 3.65 3.16 2.94 2.68 2.39 2.22 2.17 1.95 1.79 1.81; 5.91 5.75 5.47 5.3 4.98 4.79 4.62 4.55 4.38 4.19; 6 6 5.99 5.83 5.49 5.33 5.14 4.94 4.77 4.74];
imagesc(data)
Is there a way to 'smooth' the pixels in order to produce something more like this:
interp2 may be of use here. Use the data as key points, then create a finer grid of points that span the same width and height and interpolate in between the key points.
Something like this:
%// Define your data
data = [1 1 1 1 1 1 1 1 1 1; 1 1.04 1.04 1.04 1.03 1 1.01 1.01 1.03 1.01; 1.36 1.3 1.25 1.2 1.15 1.1 1.2 1.13 1.07 1.11; 3.65 3.16 2.94 2.68 2.39 2.22 2.17 1.95 1.79 1.81; 5.91 5.75 5.47 5.3 4.98 4.79 4.62 4.55 4.38 4.19; 6 6 5.99 5.83 5.49 5.33 5.14 4.94 4.77 4.74];
%// Define integer grid of coordinates for the above data
[X,Y] = meshgrid(1:size(data,2), 1:size(data,1));
%// Define a finer grid of points
[X2,Y2] = meshgrid(1:0.01:size(data,2), 1:0.01:size(data,1));
%// Interpolate the data and show the output
outData = interp2(X, Y, data, X2, Y2, 'linear');
imagesc(outData);
%// Cosmetic changes for the axes
set(gca, 'XTick', linspace(1,size(X2,2),size(X,2)));
set(gca, 'YTick', linspace(1,size(X2,1),size(X,1)));
set(gca, 'XTickLabel', 1:size(X,2));
set(gca, 'YTickLabel', 1:size(X,1));
%// Add colour bar
colorbar;
The code that's at the bottom is required because defining the finer grid ultimately increases the size of the image. I need to relabel the axes to go back to the original size.
We get this:
Small Note
I'm using MATLAB R2014a, and the default colour map is jet. You're using R2014b+ and the default colour map is parula. You won't get the same colour distribution as me, but you will get the smoothness you desire.
You can also use the pcolor(data) function with shading interp to make the color resolution smooth. No need to interpolate the data before plotting.

How to select the average value from 3 matrices

I am new to MATLAB and I need help. I have 3 matrices (A, B, and C) and I want to create a new matrix average_ABC that contains average values.
A = [ 0.3 0.5 0.9
0.14 0.36 0.1
0.9 0.5 0.14]
B = [ 0.8 0.9 0.14
0.1 0.25 0.4
0.8 0.14 0.25]
C = [0.25 0.3 0.47
0.12 0.3 0.2
0.14 0.56 0.9]
The resulting matrix will be
average_matrix = [ 0.3 0.5 0.47
0.12 0.25 0.2
0.8 0.5 0.25]
Please, any suggestion, how can I do it?
You can first concatenate your matrices along the third dimension (using cat) and then compute whatever you want using the dim parameter that is available for most functions to specify that you want to perform that operation along the third dimension.
Also you've stated that you want the average (mean), but based on your example you actually want the median. Either way, we can compute them using this method.
data = cat(3, A, B, C);
% Compute the mean
mean(data, 3)
% 0.45 0.56667 0.50333
% 0.12 0.30333 0.23333
% 0.61333 0.4 0.43
% Compute the median (which seems to be what you actually want)
median(data, 3)
% 0.3 0.5 0.47
% 0.12 0.3 0.2
% 0.8 0.5 0.25
I hope this will work
average_matrix=(A+B+C)/3.;

Show only predefined value in axes MATLAB

I would like to only show these x-values on the x-axes
xx=[0.0005 0.005 0.05 0.1 0.25 0.5 0.75 1 1.25 1.5];
Is it possible?
You can modify axis labels using XtTickLabel property. For example:
set(gca,'XTickLabel',[0.0005 0.005 0.05 0.1 0.25 0.5 0.75 1 1.25 1.5])
This will change only labels, not actual values on the plot. To check values as well you can use:
set(gca,'XTick',[0.0005 0.005 0.05 0.1 0.25 0.5 0.75 1 1.25 1.5]);
set(gca,'XScale','log'); % Your xx values seem to be logarithmic, so this can help.