The documentation for it is scarce (in contourc function):
VN is either a scalar denoting the number of lines to compute or a vector containing the values of the lines. If only one value is wanted, set 'VN = [val, val]'; If VN is omitted it defaults to 10.
I've tried a few examples, it somehow affects the amount of lines around my contour.
Does it denote how smooth my function's slope will be?
What does VN stand for?
Explanation
The contourc function does not change your data. It just plots them. Using the VN argument you can control how many contour lines are created between the highest and lowest point of the topography/function you are plotting.
If you set VN to a scalar integer value, it directly specifies the number of lines. VN=20 will create 20 levels between the highest and lowest point of your topography.
If you specify a vector of values you can exactly control at which values in your data the contour line is produced. You should take care that the values are in between min(data(:)) and max(data(:)). Otherwise the lines will not be drawn. Example VN=linspace(min(data(:)),max(data(:)),10) will create the exact same contour lines as not specifying VN.
Examples
To illustrate the effect of VN parameter I give some examples here. I use the contour function to directly plot the lines instead of just calculating them with contourcbut the effect is the same.
% Create coordinate grid
[x,y]=meshgrid(-2:0.1:2,-2:0.1:2);
% define a contour function
z=x.^2 + 2*y.^3;
% create a figure
figure();
% plot contour
contour(x,y,z);
% make axis iso scaled
axis equal
Example 1
Using the contour command without VN argument produces the following result
contour(x,y,z);
Example 2: VN=50
Setting VN to 50
contour(x,y,z,50);
Example 3: VN= vector
Setting VN explicitly to the contour values vector is used here to limit contour lines to a rather narrow range of z data:
contour(x,y,z,linspace(-0.5,0.5,10));
Related
Let's say we have the following data:
A1= [41.3251
18.2350
9.9891
36.1722
50.8702
32.1519
44.6284
60.0892
58.1297
34.7482
34.6447
6.7361
1.2960
1.9778
2.0422];
A2=[86.3924
86.4882
86.1717
85.8506
85.8634
86.1267
86.4304
86.6406
86.5022
86.1384
86.5500
86.2765
86.7044
86.8075
86.9007];
When I plot the above data using plot(A1,A2);, I get this graph:
Is there any way to make the graph look smooth like a cubic plot?
Yes you can. You can interpolate in between the keypoints. This will require a bit of trickery though. Blindly using interpolation with any of MATLAB's commands won't work because they require that the independent axes (the x-axis in your case) to increase. You can't do this with your data currently... at least out of the box. Therefore you'll have to create a dummy list of values that span from 1 up to as many elements as there are in A1 (or A2 as they're both equal in size) to create an independent axis and interpolate both arrays independently by specifying the dummy list with a finer spacing in resolution. This finer spacing is controlled by the total number of new points you want to introduce in the plot. These points will be defined within the range of the dummy list but the spacing in between each point will decrease as you increase the total number of new points. As a general rule, the more points you add the less spacing there will be and so the plot should be more smooth. Once you do that, plot the final values together.
Here's some code for you to run. We will be using interp1 to perform the interpolation for us and most of the work. The function linspace creates the finer grid of points in the dummy list to facilitate the interpolation. N would be the total number of desired points you want to plot. I've made it 500 for now meaning that 500 points will be used for interpolation using your original data. Experiment by increasing (or decreasing) the total number of points and seeing what effect this has in the smoothness of your data.
I'll also be using the Piecewise Cubic Hermite Interpolating Polynomial or pchip as the method of interpolation, which is basically cubic spline interpolation if you want to get technical. Assuming that A1 and A2 are already created:
%// Specify number of interpolating points
N = 500;
%// Specify dummy list of points
D = 1 : numel(A1);
%// Generate finer grid of points
NN = linspace(1, numel(A1), N);
%// Interpolate each set of points independently
A1interp = interp1(D, A1, NN, 'pchip');
A2interp = interp1(D, A2, NN, 'pchip');
%// Plot the data
plot(A1interp, A2interp);
I now get the following:
Let's say we have the following data:
A1= [41.3251
18.2350
9.9891
36.1722
50.8702
32.1519
44.6284
60.0892
58.1297
34.7482
34.6447
6.7361
1.2960
1.9778
2.0422];
A2=[86.3924
86.4882
86.1717
85.8506
85.8634
86.1267
86.4304
86.6406
86.5022
86.1384
86.5500
86.2765
86.7044
86.8075
86.9007];
When I plot the above data using plot(A1,A2);, I get this graph:
Is there any way to make the graph look smooth like a cubic plot?
Yes you can. You can interpolate in between the keypoints. This will require a bit of trickery though. Blindly using interpolation with any of MATLAB's commands won't work because they require that the independent axes (the x-axis in your case) to increase. You can't do this with your data currently... at least out of the box. Therefore you'll have to create a dummy list of values that span from 1 up to as many elements as there are in A1 (or A2 as they're both equal in size) to create an independent axis and interpolate both arrays independently by specifying the dummy list with a finer spacing in resolution. This finer spacing is controlled by the total number of new points you want to introduce in the plot. These points will be defined within the range of the dummy list but the spacing in between each point will decrease as you increase the total number of new points. As a general rule, the more points you add the less spacing there will be and so the plot should be more smooth. Once you do that, plot the final values together.
Here's some code for you to run. We will be using interp1 to perform the interpolation for us and most of the work. The function linspace creates the finer grid of points in the dummy list to facilitate the interpolation. N would be the total number of desired points you want to plot. I've made it 500 for now meaning that 500 points will be used for interpolation using your original data. Experiment by increasing (or decreasing) the total number of points and seeing what effect this has in the smoothness of your data.
I'll also be using the Piecewise Cubic Hermite Interpolating Polynomial or pchip as the method of interpolation, which is basically cubic spline interpolation if you want to get technical. Assuming that A1 and A2 are already created:
%// Specify number of interpolating points
N = 500;
%// Specify dummy list of points
D = 1 : numel(A1);
%// Generate finer grid of points
NN = linspace(1, numel(A1), N);
%// Interpolate each set of points independently
A1interp = interp1(D, A1, NN, 'pchip');
A2interp = interp1(D, A2, NN, 'pchip');
%// Plot the data
plot(A1interp, A2interp);
I now get the following:
I have plotted a piece-wise defined continuous linear function comprising of several oblique straight lines joined end-to-end:-
x=[0,1/4,1/2,3/4,1];
oo=[1.23 2.31 1.34 5.69 7] % edit
y=[oo(1),oo(2),oo(3),oo(4),oo(5)];
plot(x,y,'g--')
I now wish to sample points from this plot itself, say i want the y corresponding to x=0.89. How to achieve that using Matlab? Is there a special function in-built in Matlab?
Yes, there's a built-in function for that: interp1:
vq = interp1(x,v,xq) returns interpolated values of a 1-D function at specific query points using linear interpolation. Vector x contains the sample points, and v contains the corresponding values, v(x). Vector xq contains the coordinates of the query points.
[...]
See the linked documentation for further options. For example, you can specify the interpolation method (default is linear), or whether you want to extrapolate (i.e. allow for xq values to lie outside the original x range).
What is the default for the contours in a contourf function in matlab?
For example:
Z = peaks(20);
contourf(Z);
What do each of these contours represent? If I don't specify the second term in contourf e.g. contourf(Z,10) which would give 10 contour lines, how does matlab choose the number of contours?
You can look up the detailed algorithm for calculating the initial contour level step sizes from MATLABROOT\toolbox\matlab\specgraph\#specgraph\#contourgroup\refresh.m, around line 25.
Basically, Matlab divides the range into ~10 steps, but adjusts that number a bit depending on the exact value of the range of z-values.
There is no default. You are defining the number of contours by using:
Z=peaks(20);
This in effect returns an 20x20 [m,n] matrix of peaks which is stored in Z.
The ranges of the x-axis and y-axis are based on the size of array Z.
The number of contour lines and the values of the contour lines are taken from the minimum and maximum values of peaks inside the Z array.
The Z array is populated with the peaks() function which uses Normal Distribution (or Gaussian distribution).
As the documentation of the
contourf function says:
The number of contour lines and the values of the contour lines are chosen automatically based on the minimum and maximum values of Z. The ranges of the x-axis and y-axis are [1:n] and [1:m], where [m,n] = size(Z).
I create a matlab gui and have some element in it with some axes. I plot one of my desire plot in ploter1 ( first axes ) using
plot(handles.ploter1,xx); title(handles.ploter1,'Waveform');
and it is ok,but I want use specgram and plot specgram result in another axes by I dont know how can do it :(
I test
specgram(wav,N,fs,hamming(N/4),round(0.9*N/4));xlabel('time, s');
or
specgram(handles.ploter2,wav,N,fs,hamming(N/4),round(0.9*N/4));xlabel('time, s');
but return me error or nothing !!!
please help me. thank you very much
EDIT
as mentioned in the comments by bdecaf, what should work, is to set the current axes:
axes(handles.ploter2);
now, when using just
spectrogram(x,window,noverlap,F)]
the plot should be on the specified axes. If not, try:
hold on
before!
OLD
specgram or spectogram does not have a parameter for the plot. You have to define it later on.
I suggest to get the result first by:
[S,F,T]=spectrogram(x,window,noverlap,F)]
and then plot it on a specific axes:
plot(handles.ploter2, S,F)
But I am not sure about which parameter you want to plot. Please take a look at the docs.
From the docs:
[S,F,T] = spectrogram(...) returns a vector of frequencies, F, and a vector of times, T, at which the spectrogram is computed. F has length equal to the number of rows of S. T has length k (defined above) and the values in T correspond to the center of each segment.
[S,F,T] = spectrogram(x,window,noverlap,F) uses a vector F of frequencies in Hz. F must be a vector with at least two elements. This case computes the spectrogram at the frequencies in F using the Goertzel algorithm. The specified frequencies are rounded to the nearest DFT bin commensurate with the signal's resolution. In all other syntax cases where nfft or a default for nfft is used, the short-time Fourier transform is used. The F vector returned is a vector of the rounded frequencies. T is a vector of times at which the spectrogram is computed. The length of F is equal to the number of rows of S. The length of T is equal to k, as defined above and each value corresponds to the center of each segment.
[S,F,T] = spectrogram(x,window,noverlap,F,fs) uses a vector F of frequencies in Hz as above and uses the fs sampling frequency in Hz. If fs is specified as empty [], it defaults to 1 Hz.