number of contours in contourf function - matlab

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).

Related

MATLAB: Plotting 1D Conditional Distributions with kdensity stacked in a 3D figure

I have a T x 2 Matrix, where in the second column I have some daily financial returns and in the first column I have an indicator, which can assume integer values in the interval [1, 9].
I want to extract 9 different conditional distributions of my returns, conditioned on the values assumed by the indicator. At this point, I want to plot the conditional densities through a Gaussian smoothing with the function 'ksdensity' and plot them in the same 3D plot. The final output should be similar to this one: Image
I tried to reach this result by adapting the answer I found at this thread: Function.
Now suppose that x = axis of returns, y = axis of indicator possible values, z = smoothed conditional densities.
My problem is that, while in the example the meshgrid required for all the values of y have the same values of x by construction, I have different values of x (the returns) because of the conditioning.
First split your returns data into 9 vectors, according to the indicator variable. You can use accumarray for that. Then run ksdensity on each vector separately. Then plot those outputs.

matlab: upsampling a zero contour

I am using the undocumented contours function in Matlab to obtain the zero contour of a function mapping R^2 to R. The function contours() calls contourc() to obtain the zero contour in terms of array indices, and contours() then performs linear interpolation to convert from (M,N) array indices to (Y,X) data coordinates. This works well and gives a zero contour which is essentially accurate to machine precision. However, attempting to interpolate along this zero contour to obtain additional points fails, apparently because the interpolated points deviate to a small extent from the true zero contour; the resulting error is too large for the intended application.
As a simple example, one can compute a zero contour of the peaks function, compute the function values along the contour, and then compute the function values at new points interpolated along the contour. The maximum error is roughly eps(max(Z(:)) for the points found by countours/countourc and about ten orders of magnitude higher for the interpolated points.
% compute the zero contours; keep part of one contour
[X,Y,Z] = peaks(999);
XY0 = contours(X, Y, Z, [0 0]);
XY0 = XY0(:,140:(XY0(2,1)+1)); % keep only ascending values in the first contour for interpolation
% interpolate points along the zero contour
x2y = griddedInterpolant(XY0(1,:), XY0(2,:), 'linear','none');
X0i = linspace(XY0(1,1), XY0(1,end), 1e4);
Y0i = x2y(X0i);
% compute values of the function along the zero contour
Zi = interp2(X,Y,Z, XY0(1,:), XY0(2,:), 'linear', NaN);
Z0i = interp2(X,Y,Z, X0i, Y0i, 'linear', NaN);
% plot results
figure;
subplot(1,3,1); plot(XY0(1,:), XY0(2,:), '.'); hold on; plot(X0i, Y0i, 'Linewidth',1);
xlabel('X_0'); ylabel('Y_0'); title('(X_0,Y_0), (X_{0i},Y_{0i})');
subplot(1,3,2); plot(XY0(1,:), Zi, '.');
xlabel('X_0'); ylabel('Z_0'); title('f(X_0,Y_0)');
subplot(1,3,3); plot(XY0(1,:), Zi, '.'); hold on; plot(X0i, Z0i, '.');
xlabel('X_0'); ylabel('Z_0'); title('f(X_{0i},Y_{0i})');
The error is almost certainly because the interpolant does not truly follow the zero contour (i.e., having the same tangent, curvature, and indeed all higher derivatives at each point). Each interpolated point thus deviates to a small degree from the path of the zero contour. This is true for all tested methods of interpolation. If the functional form of the zero contour were known, one could fit a function to the zero contour, which would likely give satisfactory results. However, for the application motivating this question, an analytical solution of the zero contour is not possible.
Given the inadequacy of interpolation to this task, how can new points along the zero contour be obtained? The points should be such that the value of the function is as close to zero as for the set of points returned by contourc. Increasing the grid resolution globally is not an option since the memory and computational expense increase with the square of the resolution. Locally sampling at high resolution in an iterative manner over consecutive short intervals of the zero contour is an option, but would take time to implement, and I'm not aware of existing code (e.g., in the FEX) to perform such a task. Also, since contourc is closed-source, adapting it to this task is not an option.
I solved this problem by taking the interpolated (X,Y) values as an approximation of the true zero contour and reinterpolating the Y coordinate of each pair with respect to Z values of the surface flanking the approximate zero in order to locate the Y coordinate at which Z=0 for each (X,Y) pair. In so doing, uniform spacing of the interpolated X values is preserved.
For each (iX,iY) pair, where iX and iY denote the (fractional) array indices of the X and Y coordinate grids for the points interpolated along the zero contour, the approximate iY values are reinterpolated with respect to the values of Z at positions flanking (in the Y dimension) the approximate zero, i.e., at (iX,floor(iY)) and (iX,ceil(iY)). The Z values at these flanking points are themselves obtained by performing bilinear interpolation of Z at these points.
After reinterpolation, the magnitude of the error is the same as that of the points originally returned by contourc/contours.

What does "VN" optional argument in contour function stand for?

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));

How to make smooth plot with matrix that don't have the same column and line [duplicate]

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:

use specgram in axes in GUI matlab

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.