I want to plot some confidence interval graphs in MATLAB but I don't have any idea at all how to do it. I have the data in a .xls file.
Can someone give me a hint, or does anyone know commands for plotting CIs?
After reading numerous threads, here's my attempt.
% Get some random data
x = linspace(0.3, pi-0.3, 10);
Data = sin(x) + randn(1, 10)/10;
Data_sd = 0.1+randn(1,10)/30;
% prepare it for the fill function
x_ax = 1:10;
X_plot = [x_ax, fliplr(x_ax)];
Y_plot = [Data-1.96.*Data_sd, fliplr(Data+1.96.*Data_sd)];
% plot a line + confidence bands
hold on
plot(x_ax, Data, 'blue', 'LineWidth', 1.2)
fill(X_plot, Y_plot , 1,....
'facecolor','blue', ...
'edgecolor','none', ...
'facealpha', 0.3);
hold off
Mostly based on this question: Plotting with transparency
I'm not sure what you meant by confidence intervals graph, but this is an example of how to plot a two-sided 95% CI of a normal distribution:
alpha = 0.05; % significance level
mu = 10; % mean
sigma = 2; % std
cutoff1 = norminv(alpha, mu, sigma);
cutoff2 = norminv(1-alpha, mu, sigma);
x = [linspace(mu-4*sigma,cutoff1), ...
linspace(cutoff1,cutoff2), ...
linspace(cutoff2,mu+4*sigma)];
y = normpdf(x, mu, sigma);
plot(x,y)
xlo = [x(x<=cutoff1) cutoff1];
ylo = [y(x<=cutoff1) 0];
patch(xlo, ylo, 'b')
xhi = [cutoff2 x(x>=cutoff2)];
yhi = [0 y(x>=cutoff2)];
patch(xhi, yhi, 'b')
See e.g. these m-files on Matlab File Exchange:
plot confidence intervals
confplot
Related
My goal is to fit a sinusoid to data goming from a datalogger using Octave.
The datalogger logs force which is produced using an excenter, so it theoretically should be a sine wave.
I could not find any hint on how to do this elsewhere.
Currently I'm using the function "splinefit" followd by "ppval" to fit my data but I don't realy get the results I hoped from it...
Has anybody an idea how I could fit a sinusoid to my data?
Here's my current code I use to fit the data and a scrennshot of the result:
## splinefit force left
spfFL = splinefit(XAxis,forceL,50);
fitForceL=ppval(spfFL,XAxis);
##middle force left
meanForceL=mean(fitForceL);
middleedForceL=fitForceL-meanForceL;
result spline fit
on the X-Axis I have the 30'000 measurepoints or logs
on the Y-Axis I have the actual measured force values
the data comes from the datalogger in a .csv-file like this
You can do a simple regression using the sine and cosine of your (time) input as your regression features.
Here's an example
% Let's generate a dataset from a known sinusoid as an example
N = 1000;
Range = 100;
w = 0.25; % known frequency (e.g. from specs or from fourier analysis)
Inputs = randi(Range, [N, 1]);
Targets = 0.5 * sin( w * Inputs + pi/3 ) + 0.05 * randn( size( Inputs ) );
% Y = A + B sin(wx) + C cos(wx); <-- this is your model
Features = [ ones(N, 1), sin(w * Inputs), cos(w * Inputs) ];
Coefs = pinv(Features) * Targets;
A = Coefs(1); % your solutions
B = Coefs(2);
C = Coefs(3);
% print your nice solution against the input dataset
figure('position', [0, 0, 800, 400])
ax1 = axes()
plot(Inputs, Targets, 'o', 'markersize', 10, ...
'markeredgecolor', [0, 0.25, 0.5], ...
'markerfacecolor', [0, 0.5, 1], ...
'linewidth', 1.5)
set(ax1, 'color', [0.9, 0.9, 0.9])
ax2 = axes()
X = 1:0.1:Range;
plot( X, A + B*sin(w * X) + C*cos(w * X), 'k-', 'linewidth', 5 ); hold on
plot( X, A + B*sin(w * X) + C*cos(w * X), 'g-', 'linewidth', 2 ); hold off
set(ax2, 'xlim', get(ax1, 'xlim'), 'ylim', get(ax1, 'ylim'), 'color', 'none')
You could do a least squares optimization, using fminsearch
% sine to fit (in your case your data)
x = 0:0.01:50;
y = 2.6*sin(1.2*x+3.1) + 7.3 + 0.2*rand(size(x)); % create some noisy sine with known parameters
% function with parameters
fun = #(x,p) p(1)*sin(p(2)*x+p(3)) + p(4); % sine wave with 4 parameters to estimate
fcn = #(p) sum((fun(x,p)-y).^2); % cost function to minimize the sum of the squares
% initial guess for parameters
p0 = [0 0 0 0];
% parameter optimization
par = fminsearch(fcn, p0);
% see if estimated parameters match measured data
yest = fun(x, par)
plot(x,y,x,yest)
Replace x and y with your data. The par variable contains the parameters of the sine, as defined in fun.
Considering two normal (Gaussian) distributions: the first is characterized by μ=10, σ=3. The second is characterized by μ=10, σ=1
First calculate the Probability Density Function of these two distributions. You can calculate it by using this code,
function f = gauss_distribution(x, mu, s)
p1 = -.5 * ((x - mu)/s) .^ 2;
p2 = (s * sqrt(2*pi));
f = exp(p1) ./ p2;
Suppose you have two dataset x1 and x2. Then,
f1 = gauss_distribution(x1,10,3);
f2 = gauss_distribution(x2,10,1);
Now the plotting can be done like this,
figure;
plot(x1,f1);
hold on;
plot(x2,f2,'r');
xlabel('name of label');
legend('1st dataset', '2nd dataset');
MATLAB has greatly simplified this process for many distributions with the makedist, pdf, and cdf command. Code and resulting plots below for reference.
pd1 = makedist('Normal',10,3);
pd2 = makedist('Normal',10,1);
X = [0:.01:20]';
% PDF plot
figure, hold on, box on
p(1) = plot(X,pdf(pd1,X),'b-','DisplayName','N(\mu = 10, \sigma = 3)')
p(2) = plot(X,pdf(pd2,X),'k-','DisplayName','N(\mu = 10, \sigma = 1)')
title('Two Normal Distributions (PDFs)')
xlabel('X')
ylabel('PDF')
legend('show')
set(p,'LineWidth',2.2)
% CDF plot
figure, hold on, box on
p(1) = plot(X,cdf(pd1,X),'b-','DisplayName','N(\mu = 10, \sigma = 3)')
p(2) = plot(X,cdf(pd2,X),'k-','DisplayName','N(\mu = 10, \sigma = 1)')
title('Two Normal Distributions (CDFs)')
xlabel('X')
ylabel('CDF')
legend('show','Location','southeast')
set(p,'LineWidth',2.2)
I need to plot a ROC curve in matlab. I have two arrays, one containing the true positive rate and one containing the false positive rate. I've tried both plotroc and perfcurve with the two arrays as input, but it doesn't seems to work. There is another way for plotting ROC curve with the data I have?
EDIT
I'm posting an image in order to answer to Tasos Papastylianou:
simply plotting the two array it does not really seems a ROC curve :S
EDIT2
Upload the image with the array inverted, still not looking like a ROC!
EDIT3
Image showing the plot of my ROC curve, normalized in [0,1]
[]3
I thought I'd post a proper answer with a nice ROC curve example, demonstrating the stuff we discussed in the comments:
%% Create datasets
[X,Y] = ndgrid(1:100,1:100);
% Ground Truth image
Circle= zeros(100); Circle((X-50).^2 + (Y-50).^2 - 500 <= 0) = 1;
% Test image (parameterised by threshold)
pkg load statistics % if using octave - needed for 'mvnpdf'
pkg load image % if using octave - needed for 'mat2gray'
Gaussian = mvnpdf([X(:), Y(:)], [45, 45], [500,0;0,500]);
Gaussian = reshape(Gaussian, size(X));
Gaussian = mat2gray(Gaussian);
%% Generate ROC curve for a range of thresholds
ThresholdRange = 0 : 0.025 : 1;
TPs = zeros(size(ThresholdRange));
FPs = zeros(size(ThresholdRange));
Ind = 0;
for Threshold = ThresholdRange
Ind = Ind + 1;
TP = Circle .* (Gaussian > Threshold);
T = Circle;
TPR = sum(TP(:)) / sum(T(:));
TPs(Ind) = TPR;
FP = (1 - Circle) .* (Gaussian > Threshold);
N = (1 - Circle);
FPR = sum(FP(:)) / sum(N(:));
FPs(Ind) = FPR;
end
%% Plotski curvski
plot(FPs, TPs, 'linewidth', 3, 'marker', 'o', 'markersize',10,'markeredgecolor', 'k', 'markerfacecolor', 'g');
hold on;
plot(ThresholdRange, ThresholdRange, 'r-.', 'linewidth', 3);
axis([0,1,0,1]);
title('Les Curves du ROC! Ooh-la-la!', 'fontsize', 16);
xlabel('Le Rate des Positifs Falses! Oh mon dieu!', 'fontsize', 14);
ylabel('Le Rate des Positifs Vrais! Magnifique!', 'fontsize', 14);
grid on;
I resolved thanks to the comments provided by #TasosPapastylianou. For getting better results in plotting, I sort the two array on the x-axis (or the False Positive Rates). Thanks again to #TasosPapastylianou !!!
I am trying to write some code to generate a plot similar to the one below on matlab (taken from here):
I have a set of points on a curve (x_i,y_i,z_i). Each point generates a Gaussian distribution (of mean (x_i,y_i,z_i) and covariance matrix I_3).
What I did is I meshed the space into npoint x npoints x npoints and computed the sum of the probability densities for each of the 'sources' (x_i,y_i,z_i) in each point (x,y,z). Then, if the value I get is big enough (say 95% of the maximum density), I keep the point. otherwise I discard it.
The problem with my code is that it is too slow (many for loops) and the graph I get doesn't look like the one below:
Does anyone know whether there is a package to get a similar plot as the one below?
Using isosurface we can do reasonably well. (Although I'm not honestly sure what you want, I think this is close:
% Create a path
points = zeros(10,3);
for ii = 2:10
points(ii, :) = points(ii-1,:) + [0.8 0.04 0] + 0.5 * randn(1,3);
end
% Create the box we're interested in
x = linspace(-10,10);
y = x;
z = x;
[X,Y,Z] = meshgrid(x,y,z);
% Calculate the sum of the probability densities(ish)
V = zeros(size(X));
for ii = 1:10
V = V + 1/(2*pi)^(3/2) * exp(-0.5 * (((X-points(ii,1)).^2 + (Y-points(ii,2)).^2 + (Z-points(ii,3)).^2)));
end
fv = isosurface(X,Y,Z,V, 1e-4 * 1/(2*pi)^(3/2), 'noshare');
fv2 = isosurface(X,Y,Z,V, 1e-5 * 1/(2*pi)^(3/2), 'noshare');
p = patch('vertices', fv.vertices, 'faces', fv.faces);
set(p,'facecolor', 'none', 'edgecolor', 'blue', 'FaceAlpha', 0.05)
hold on;
p2 = patch('vertices', fv2.vertices, 'faces', fv2.faces);
set(p2,'facecolor', 'none', 'edgecolor', 'red', 'FaceAlpha', 0.1)
scatter3(points(:,1), points(:,2), points(:,3));
I have two classes(normally distributed), C1 and C2, each defined by their mean and standard deviation. I want to be able to visualize the pdf plot of a normal distributions and the classification boundary between the two. Currently I have the code to plot the distributions but I'm not sure how to go about plotting the decision boundary. Any ideas would be appreciated. I have included a sample of what I want to plot. 1
Many thanks!
This is what I came up with:
% Generate some example data
mu1 = -0.5; sigma1 = 0.7; mu2 = 0.8; sigma2 = 0.5;
x = linspace(-8, 8, 500);
y1 = normpdf(x, mu1, sigma1);
y2 = normpdf(x, mu2, sigma2);
% Plot it
figure; plot(x, [y1; y2])
hold on
% Detect intersection between curves; choose threshold so you get the whole
% intersection (0.0001 should do unless your sigmas are very large)
ind = y1 .* y2 > 0.0001;
% Find the minimum values in range
minVals = min([y1(ind); y2(ind)]);
if ~isempty(minVals)
area(x(ind), minVals)
end
I don't know if this is the best way to do what you want, but it seems to work.