Changing the length of x axis in MATLAB - matlab

I have the following code.
% Generate message signal
t1 = -1:0.1:1;
message_sig = rectpuls(t1);
L = length(message_sig);
figure(2)
stairs(0:L-1:L, 'linewidth',1.5);
axis([0 L -1 2]);
title('Message Signal');
When i run this, the length of my x axis is from 0 to 20.
How can i reduce it to say 0 to 8, while plotting the same bit pattern. Because when i try modulating and add noise, the whole plot (noise modulated signal) is blue and needs to be zoomed alot to see accurately.
So can someone help me with a code that could solve this.

simply use xlim([0,8]), that will restrict the x-axis from going beyond 8, or edit your axis call to be axis([0,8,-1,2])
UPDATE
Assuming you have the image processing toolbox, it is really simple
in = [0,1,0];
imresize(in,[1,8],'nearest');
This will take that pattern and expand it to whatever dimension you want.

Related

How to resize the axes of an graph on Matlab?

I need ideas to resize my axes to have a much more airy graph to better visualize and calculate the gain between the different curves.
I used the code : axis([0 6 1e-3 1e0]) or xlim([0 6]); ylim([1e-3 1e0])
I would like to have for example my curve with: xlim([0:0.2:6]) (just the idea, otherwise it's wrong on matlab).
Thank you!
If I understand what you want, you need more XTicks in the x limits mentioned. After you plot just:
set(gca,'XTick',0:0.2:6)
another way is to write:
h=plot(.... whatever you plot...
h.XTick=0:0.2:6
Logarithmic Plot:
To create the axes the function xticks() and yticks() can be used to set the intervals, start and endpoints. xticks() and yticks() essentially take vectors that define all the ticks on the scales/axes. Just in case you'd like to also edit the interval along the y-axis. This vector can be created by raising each element in the vector (-3,1:0) to be an exponent with a base of 10. Finally, setting gca (the current axis) to logarithmic will allow the vertical spacing between the ticks to be evenly distributed.
axis([0 6 1e-3 1e0]);
Start = 0; Interval = 0.2; End = 6;
X_Vector = (Start: Interval: End);
xticks(X_Vector);
Y_Vector = 10.^(-3: 1: 0);
yticks(Y_Vector);
set(gca, 'YScale', 'log');
title("Logarithmic Plot");
grid;
Ran using MATLAB R2019b

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.

Diffraction using fourier transform in Matlab

I am very new to Matlab and am trying to implement the following fresnel diffraction using the fourier transform:
This is taken from the following wikipedia page: http://en.wikipedia.org/wiki/Fresnel_diffraction
I am trying a square aperture of width 5 cm.
clc;clear;
lambda=1*10^-6;
w=.05;
z=2.0;
k=(2*pi)/lambda;
x1=linspace(-0.2,0.2,2048);
y1=linspace(-0.2,0.2,2048);
U1=((abs(x1)<=(w)/2))&((abs(y1)<=(w)/2));
u1=double(U1);
figure(1)
plot(x1,u1)
g=u1'*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
G=fftshift(fft2(g));
h=(exp(1i*k*z)/(1i*lambda*z))*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
H=fftshift(fft2(h));
u2=H*G;
figure(2)
plot(x1,abs(u2));
When I plot the field u2, for any of the distances, z, that I try, it just shows up like some random pattern and not the expected diffraction pattern for a square aperture.
Like I said, I am very new to MATLAB and find it difficult to understand. I think I am making this more complicated than it needs to be, and am implementing the integrals incorrectly.
Any pointers or advice? I am quite stuck...
Thanks!
Looks like you want to simulate Fresnel diffraction with this code.
With a few changes you can view the actual image. Shown here is the amplitude. The intensity would be u2.*conj(u2).
Note however that critical sampling will occur much further away than 2 meters, more like 100 meters, for the physical parameters you are using.
Also there needs to be some additional re-scaling on the output plane, not done here. Otherwise the diffraction pattern will get very small for low Fresnel numbers.
clc;clear;
N=1048;
L=0.4;
lambda=1*10^-6;
w=.05;
z=500.0;
k=(2*pi)/lambda;
src_delta = L/N;
critical_sampling_z = N*src_delta^2/lambda;
[x1 y1] = meshgrid((-N/2 : N/2-1) * src_delta);
X = double(abs(x1)<w/2); Y = double(abs(y1)<w/2);
u1 = X.*Y;
figure(1);
colormap(gray); imagesc(mat2gray(u1));
g=u1'*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
G=fftshift(fft2(g));
h=(exp(1i*k*z)/(1i*lambda*z))*exp(1i*(pi/(lambda*z))*(x1.^2+y1.^2));
H=fftshift(fft2(h));
u2=H*G;
figure(2);
colormap(gray); imagesc(mat2gray(abs(u2)));

Histogram (hist) not starting (and ending) in zero

I'm using the Matlab function "hist" to estimate the probability density function of a realization of a random process I have.
I'm actually:
1) taking the histogram of h0
2) normalizing its area in order to get 1
3) plotting the normalized curve.
The problem is that, no matter how many bins I use, the histogram never start from 0 and never go back to 0 whereas I would really like that kind of behavior.
The code I use is the following:
Nbin = 36;
[n,x0] = hist(h0,Nbin);
edge = find(n~=0,1,'last');
Step = x0(edge)/Nbin;
Scale_factor = sum(Step*n);
PDF_h0 = n/Scale_factor;
hist(h0 ,Nbin) %plot the histogram
figure;
plot(a1,p_rice); %plot the theoretical curve in blue
hold on;
plot(x0, PDF_h0,'red'); %plot the normalized curve obtained from the histogram
And the plots I get are:
If your problem is that the plotted red curve does not go to zero: you can solve that adding initial and final points with y-axis value 0. It seems from your code that the x-axis separation is Step, so it would be:
plot([x0(1)-Step x0 x0(end)+Step], [0 PDF_h0 0], 'red')

Matlab - Signal Noise Removal

I have a vector of data, which contains integers in the range -20 20.
Bellow is a plot with the values:
This is a sample of 96 elements from the vector data. The majority of the elements are situated in the interval -2, 2, as can be seen from the above plot.
I want to eliminate the noise from the data. I want to eliminate the low amplitude peaks, and keep the high amplitude peak, namely, peaks like the one at index 74.
Basically, I just want to increase the contrast between the high amplitude peaks and low amplitude peaks, and if it would be possible to eliminate the low amplitude peaks.
Could you please suggest me a way of doing this?
I have tried mapstd function, but the problem is that it also normalizes that high amplitude peak.
I was thinking at using the wavelet transform toolbox, but I don't know exact how to reconstruct the data from the wavelet decomposition coefficients.
Can you recommend me a way of doing this?
One approach to detect outliers is to use the three standard deviation rule. An example:
%# some random data resembling yours
x = randn(100,1);
x(75) = -14;
subplot(211), plot(x)
%# tone down the noisy points
mu = mean(x); sd = std(x); Z = 3;
idx = ( abs(x-mu) > Z*sd ); %# outliers
x(idx) = Z*sd .* sign(x(idx)); %# cap values at 3*STD(X)
subplot(212), plot(x)
EDIT:
It seems I misunderstood the goal here. If you want to do the opposite, maybe something like this instead:
%# some random data resembling yours
x = randn(100,1);
x(75) = -14; x(25) = 20;
subplot(211), plot(x)
%# zero out everything but the high peaks
mu = mean(x); sd = std(x); Z = 3;
x( abs(x-mu) < Z*sd ) = 0;
subplot(212), plot(x)
If it's for demonstrative purposes only, and you're not actually going to be using these scaled values for anything, I sometimes like to increase contrast in the following way:
% your data is in variable 'a'
plot(a.*abs(a)/max(abs(a)))
edit: since we're posting images, here's mine (before/after):
You might try a split window filter. If x is your current sample, the filter would look something like:
k = [L L L L L L 0 0 0 x 0 0 0 R R R R R R]
For each sample x, you average a band of surrounding samples on the left (L) and a band of surrounding samples on the right. If your samples are positive and negative (as yours are) you should take the abs. value first. You then divide the sample x by the average value of these surrounding samples.
y[n] = x[n] / mean(abs(x([L R])))
Each time you do this the peaks are accentuated and the noise is flattened. You can do more than one pass to increase the effect. It is somewhat sensitive to the selection of the widths of these bands, but can work. For example:
Two passes:
What you actually need is some kind of compression to scale your data, that is: values between -2 and 2 are scale by a certain factor and everything else is scaled by another factor. A crude way to accomplish such a thing, is by putting all small values to zero, i.e.
x = randn(1,100)/2; x(50) = 20; x(25) = -15; % just generating some data
threshold = 2;
smallValues = (abs(x) <= threshold);
y = x;
y(smallValues) = 0;
figure;
plot(x,'DisplayName','x'); hold on;
plot(y,'r','DisplayName','y');
legend show;
Please do not that this is a very nonlinear operation (e.g. when you have wanted peaks valued at 2.1 and 1.9, they will produce very different behavior: one will be removed, the other will be kept). So for displaying, this might be all you need, for further processing it might depend on what you are trying to do.
To eliminate the low amplitude peaks, you're going to equate all the low amplitude signal to noise and ignore.
If you have any apriori knowledge, just use it.
if your signal is a, then
a(abs(a)<X) = 0
where X is the max expected size of your noise.
If you want to get fancy, and find this "on the fly" then, use kmeans of 3. It's in the statistics toolbox, here:
http://www.mathworks.com/help/toolbox/stats/kmeans.html
Alternatively, you can use Otsu's method on the absolute values of the data, and use the sign back.
Note, these and every other technique I've seen on this thread is assuming you are doing post processing. If you are doing this processing in real time, things will have to change.