Finding time spent by data outside a bin in MATLAB - matlab

I have the following graph:
x-axis represents time and both x and y axis data are discrete. I want to find the time spent by the graph during the time it exits the bin marked by yellow and red lines and when it comes back. The problem is that x axis data is discrete and and I want the duration x(t') - x(t).
Suppose the graph cuts yellow line at say n= 3.2 and goes outside the bin and then again cuts the yellow line at say n = 5.1, then I want the duration (5.1-3.2). SImilarly for the red line as well. Any idea on how can I do that?
The MATLAB code to generate the data set is:
mu =4;
x(1)=0.2; % x_{0}
nn=1:1001;
for n=1:1000
x(n+1) = mu*x(n)*(1-x(n));
end
figure;
plot(nn,x);
hold on;
plot([1 1010],[0.49 0.49]);
xlabel('n');
ylabel('x_{n}');
title('Plot of the equation: x_{n+1} = 4x_{n}(1-x_{n}) for x_{0} = 0.2 with
a bin of width 0.01 from x_{n} = 0.49 to x_{n+1}= 0.50');
hold on;
plot([1 1010],[0.50 0.50]);

I hope i interpreted this correctly when answering. So you're looking for values of n where they are x_n are 0.5 and 0.49. this will take two matrices and a while or for loop that will go for the 1000 iterations. Inside that put two if statements one for 0.5 and one for 0.49. Inside each one set a matrix to store the n value

Related

Matlab break X axis

I am having a trouble in showing a plot which runs from 0-10K.
Currently I have calculation running from 0-100 and it looks great.
Currently:
Now I want to add one X points which is 10K
And it looks this way:
How do I keep it from 0-100 and show only then the jumps to 10K ?
Is it even possible ?
The problem is that 0-100 is very small portion in 10K so it looks bad.
You could plot your one outlier point at a closer x coordinate, then adjust the XTick and XTickLabel properties to make it appear as though there is a break in the plot range. For example:
plot([1:20 25], 1./[1:20 10000]);
set(gca, 'XTick', [2:2:20 25], ...
'XTickLabel', strtrim(cellstr(int2str([2:2:20 10000].'))));
And here's the plot this creates:
Maybe you can try to sample the x points (for the second plot) in different gaps. You can combine two arrays of x sample points (each array with a fixed gap but the first gap is much smaller than the second gap). then you plot the combined points.
Here's a code example:
clear;
close all;
clc;
gap1 = 0.2;
x_left = 1:gap1:3;
gap2 = 0.5;
x_right = 3+gap2:gap2:6;
x_ticks_for_plot = [x_left x_right];
x=x_ticks_for_plot;
y = sin(x);
plot(x,y);
xticks(x_ticks_for_plot);
And the plot:
In your case the second gap should be much bigger than the first but it's the same idea.

plotting line between points in a loop goes wrong

I am currently trying to simulate a random walk. The idea is to choose a random number between 0 and 2*pi and let the random walker go in that direction. Here is what I tried to do to simulate such a random walk:
before=[0 0]; %start in (0,0)
while 1
x=rand;
x=x*2*pi; %// choose random angle
increment=[cos(x),sin(x)] %// increments using the sine and cosine function
now=before+increment;
plot(before, now)
hold on
before=now;
pause(1);
end
I expect this program to plot lines and each new line starts at the ending point of the previous line, but this does not happen. I have no clue why it is not working.
You got the syntax for plot wrong, which is plot(X,Y). Change the call to
plot([before(1), now(1)], [before(2), now(2)])
and your program should work as expected.
Here is an improved version that does all the calculation vectorized and gives you two choices of output. The first one displays all at once and is very fast. The second one takes a lot of time depending on the amount of samples.
pts = [0,0]; % starting point
N = 10000; % sample count
x = rand(N,1) * 2*pi; % random angle
% calculate increments and points
inc = [cos(x),sin(x)];
pts = [pts;cumsum(inc,1)];
% plot result at once
figure;
plot(pts(:,1),pts(:,2));
% plot results in time steps
figure; hold on;
for i = 1:size(pts,1)
plot(pts(i:i+1,1),pts(i:i+1,2))
pause(1)
end
Here is an example of the output:

How to plot phasors of signals?

I have 3 singals and I'm trying to plot their phasors and their sum. I need to plot them end to end to demonstrate phasor addition. That is, the first phasor must start from the origin. The second phasor must start from the end of the first phasor. The third phasor must start from the end of the second one. In this way, the end point of the third phasor is the resulting phasor (considering that it starts at the origin). Horizontal and vertical axes are the real and imaginary axes, respectively in range of [-30, 30].
I just started using matlab today and this is due the night. I tried using plot, plot2, plot3, compass, and several ways but with all of them i failed. Compass was the closest to success.
I have amplitude and phase values of each phasor.
So how can I accomplish this task? Can you help me to draw two of phasors?
Any help is appreciated.
Thank you!
Related Example: from http://fourier.eng.hmc.edu/e84/lectures/ch3/node2.html
[example by spektre]
The following example should get you started:
First, the three phasors are defined.
% Define three complex numbers by magnitude and phase
ph1 = 20*exp(1i*0.25*pi);
ph2 = 10*exp(1i*0.7*pi);
ph3 = 5*exp(1i*1.2*pi);
Then, using cumsum, a vector containing ph1, ph1+ph2, ph1+ph2+ph3 is calculated.
% Step-wise vector sum
vecs = cumsum([ph1; ph2; ph3]);
vecs = [0; vecs]; % add origin as starting point
The complex numbers are plotted by real and imaginary part.
% Plot
figure;
plot(real(vecs), imag(vecs), '-+');
xlim([-30 30]);
ylim([-30 30]);
xlabel('real part');
ylabel('imaginary part');
grid on;
This produces the following figure:
figure(1); hold on;
ang = [0.1 0.2 0.7] ; % Angles in rad
r = [1 2 4] ; % Vector of radius
start = [0 0]
for i=1:numel(r)
plot([start(1) start(1)+r(i)*cos(ang(i))],[start(2) start(2)+r(i)*sin(ang(i))],'b-+')
start=start+[r(i)*cos(ang(i)) r(i)*sin(ang(i))]
end
plot([0 start(1)],[0 start(2)],'r-')

Adjusting the x-axis scale on a bar chart in MATLAB

I am trying to adjust the scale of the x-axis so that the values are closer together, but I am not able to do so.
I need the output to be like this photo:
However, what I actually get is the photo below:
Here's the code I have written to reproduce this error:
x = [0.1 1 10 100 1000 10000];
y = [1.9904 19.8120 82.6122 93.0256 98.4086 99.4016];
figure;
bar(x,y);
ylabel('Y values');
xlabel('X values');
set(gca,'XTick', [0.1 1 10 100 1000 10000])
How can I adjust the x-axis so that it looks like the first photo?
Because your data has such huge dynamic range, and because of the linear behaviour of the x axis, your graph is naturally going to appear like that. One compromise that I can suggest is that you transform your x data so that it gets mapped to a smaller scale, then remap your x data so that it falls onto a small exponential scale. After, simply plot the data using this remapped scale, then rename the x ticks so that they have the same values as your x data. To do this, I would take the log10 of your data first, then apply an exponential to this data. In this way, you are scaling the x co-ordinates down to a smaller dynamic range. When you apply the exponential to this smaller range, the x co-ordinates will then spread out in a gradual way where higher values of x will certainly make the value go farther along the x-axis, but not too far away like you saw in your original plot.
As such, try something like this:
x = [0.1 1 10 100 1000 10000]; %// Define data
y = [1.9904 19.8120 82.6122 93.0256 98.4086 99.4016];
xplot = (1.25).^(log10(x)); %// Define modified x values
figure;
bar(xplot,y); %// Plot the bar graph on the modified scale
set(gca,'XTick', xplot); %// Define ticks only where the bars are located
set(gca,'XTickLabel', x); %// Rename these ticks to our actual x data
This is what I get:
Note that you'll have to play around with the base of the exponential, which is 1.25 in what I did, to suit your data. Obviously, the bigger the dynamic range of your x data, the smaller this exponent will have to be in order for your data to be closer to each other.
Edit from your comments
From your comments, you want the bars to be equidistant in between neighbouring bars. As such, you simply have to make the x axis linear in a small range, from... say... 1 to the total number of x values. You'd then apply the same logic where we rename the ticks on the x axis so that they are from the true x values instead. As such, you only have to change one line, which is xplot. The other lines should stay the same. Therefore:
x = [0.1 1 10 100 1000 10000]; %// Define data
y = [1.9904 19.8120 82.6122 93.0256 98.4086 99.4016];
xplot = 1:numel(x); %// Define modified x values
figure;
bar(xplot,y); %// Plot the bar graph on the modified scale
set(gca,'XTick', xplot); %// Define ticks only where the bars are located
set(gca,'XTickLabel', x); %// Rename these ticks to our actual x data
This is what I get:

Relative Frequency Histograms and Probability Density Functions

The function called DicePlot simulates rolling 10 dice 5000 times.
The function calculates the sum of values of the 10 dice of each roll, which will be a 1 ⇥ 5000 vector, and plot relative frequency histogram with edges of bins being selected in where each bin in the histogram represents a possible value of for the sum of the dice.
The mean and standard deviation of the 1 ⇥ 5000 sums of dice values will be computed, and the probability density function of normal distribution (with the mean and standard deviation computed) on top of the relative frequency histogram will be plotted.
Below is my code so far - What am I doing wrong? The graph shows up but not the extra red line on top? I looked at answers like this, and I don't think I'll be plotting anything like the Gaussian function.
% function[]= DicePlot()
for roll=1:5000
diceValues = randi(6,[1, 10]);
SumDice(roll) = sum(diceValues);
end
distr=zeros(1,6*10);
for i = 10:60
distr(i)=histc(SumDice,i);
end
bar(distr,1)
Y = normpdf(X)
xlabel('sum of dice values')
ylabel('relative frequency')
title(['NumDice = ',num2str(NumDice),' , NumRolls = ',num2str(NumRolls)]);
end
It is supposed to look like
But it looks like
The red line is not there because you aren't plotting it. Look at the documentation for normpdf. It computes the pdf, it doesn't plot it. So you problem is how do you add this line to the plot. The answer to that problem is to google "matlab hold on".
Here's some code to get you going in the right direction:
% Normalize your distribution
normalizedDist = distr/sum(distr);
bar(normalizedDist ,1);
hold on
% Setup your density function using the mean and std of your sample data
mu = mean(SumDice);
stdv = std(SumDice);
yy = normpdf(xx,mu,stdv);
xx = linspace(0,60);
% Plot pdf
h = plot(xx,yy,'r'); set(h,'linewidth',1.5);