ploting a function under condition with Matlab [duplicate] - matlab

This question already has an answer here:
Multiple colors in the same line
(1 answer)
Closed 4 years ago.
I am looking for a solution to this problem:
consider a function f (x) = 2x + 1, with x belonging to [0, 1000]. Draw the representative curve of f as a function of x, so that if ||f (x)|| <3 the representative curve of f is in red color and else represent the curve of f in blue color.
Help me because I am a new user of Matlab software

The code below should do the trick:
% Obtain an array with the desired values
y = myfunc(x);
% Get a list of indices to refer to values of y
% meeting your criteria (there are alternative ways
% to do it
indInAbs = find((abs(y)<3));
indOutAbs = find((abs(y)>=3));
% Create two arrays with y-values
% within the desired range
yInAbs = y(indInAbs);
xInAbs = x(indInAbs);
% Create two arrays with y-values
% outside the desired range
yOutAbs = y(indOutAbs);
xOutAbs = x(indOutAbs);
% Plot the values
figure(1);
hold on;
plot( xInAbs, yInAbs, 'r')
plot( xOutAbs, yOutAbs, 'b')
legend('in abs', 'out abs', 'location', 'best')
There are alternative ways to do it which could be more efficient and elegant. However, this is a quick and dirty solution.

Your threshold cannot be too low, otherwise it has not enough data to plot (if threshold=3) or cannot see the blue part. Here I use 500 such that you can see.
function plotSeparate
clc
close all
k=0
threshold=500
for x=1:0.5:1000
k=k+1
y=f(x)
if abs(y)<threshold
t(k,:)=[x,y];
else
s(k,:)=[x,y];
end
end
plot(s(:,1),s(:,2),'-r',t(:,1),t(:,2),'-b')
end
function y=f(x)
y=2*x+1;
end

Related

Using Trapezium Rule on any function and show a graph

I have successfully managed to create a code in which I can estimate the area beneath the curve using the Trapezium rule. What I am struggling to do is plot the corresponding graph. I've used x^2 as the example and in the image I've attached a=-5, b=5 and n=3. And the original x^2 graph is not coming up but rather a merge between the blue and green lines. Can someone help fix this? Thank you.
Figure 1
% Trapezium Rule
f=#H; % Input Function
a=input('Enter lower limit a: ');
b=input('Enter upper limit b: ');
n=input('Enter the no. of interval: ');
h=(b-a)/n;
sum=0;
% Sum of f(x_1) to f(x_n+1)
for k=1:1:n+1
x(k)=a+k*h;
y(k)=f(x(k));
sum=sum+y(k);
end
hold on
plot(x, y,'bo-');
% drawing of the function
plot([x(1:end); x(1:end)], [zeros(1,length(y)); y(1:end)], 'r-');
% vertical lines from the points
plot([x(1:end-1); x(2:end)], [y(1:end-1) ; y(1: end)], 'g--');
% Meant to be forming a trapizium
hold off
answer = (h*0.5)*(sum);
% answer=h/2*(f(a)+f(b)+2*sum);
fprintf('\n The value of integration is %f',answer);
function y = H(x)
y = x.^2;
end
Your green line does not go from the same value to the same value! It foes from one to the next. You forgot that.
% the only reason you do -1 is so the last y can go to the end! The same as x
plot([x(1:end-1); x(2:end)], [y(1:end-1) ; y(2: end)], 'g--');

MATLAB: scatter plot from where each point has its own color [duplicate]

This question already has answers here:
3D scatter plot with 4D data
(2 answers)
Closed 6 years ago.
Suppose I have a situation as follows:
clc; clear;
n = 1001;
m = 1000;
X = linspace(0,1,n);
Y = linspace(0,1,n);
randcolor = rand(m,3);
colorcode = randi(m,m,m);
For i = 1, ..., n and j = 1, ...,n, I would like to plot the points (X(i),Y(j))'s where the RBG color for (X(i),Y(j)) is randcolor(colorcode(i,j),:). I tried to do this the silly way: first declare
figure; hold on;
then do 2 nested loops, n steps each, and use plot to plot a single point n x n times:
for i = 1:n
for j = 1:n
plot(X(i),Y(j),'Marker','o',...
'MarkerEdgeColor',randcolor(colorcode(i,j),:),...
'MarkerFaceColor',randcolor(colorcode(i,j),:));
end
end
This technically worked but it was slow and MATLAB ate up all of my memory when n was increased. What's a better way to do this please?
p.s. In my actual problem, colorcode isn't actually randomly assigned. Rather, it's assigned based on some divergence criterion for a filled Julia set.
You want to use scatter instead of plot which allows you to specify the size and color of each point individually.
colors = rand(numel(X), 3);
S = scatter(X, Y, 100, colors);

matlab plotting a family of functions

Generate a plot showing the graphs of
y=(2*a+1)*exp(-x)-(a+1)*exp(2*x)
in the range x ∈ <-2, 4> for all integer values of a between -3 and 3
I know how to make typical plot for 2 values and set a range on the axes, but how to draw the graph dependent on the parameter a?
To elaborate on Ben Voigt's comment: A more advanced technique would be to replace the for-loop with a call to bsxfun to generate a matrix of evaluations of M(i,j) = f(x(i),a(j)) and call plot with this matrix. Matlab will then use the columns of the matrix and plot each column with individual colors.
%%// Create a function handle of your function
f = #(x,a) (2*a+1)*exp(-x)-(a+1)*exp(2*x);
%%// Plot the data
x = linspace(-2, 4);
as = -3:3;
plot(x, bsxfun(f,x(:),as));
%%// Add a legend
legendTexts = arrayfun(#(a) sprintf('a == %d', a), as, 'uni', 0);
legend(legendTexts, 'Location', 'best');
You could also create the evaluation matrix using ndgrid, which explicitly returns all combinations of the values of x and as. Here you have to pay closer attention on properly vectorizing the code. (We were lucky that the bsxfun approach worked without having to change the original f.)
f = #(x,a) (2*a+1).*exp(-x)-(a+1).*exp(2*x); %// Note the added dots.
[X,As] = ndgrid(x,as);
plot(x, f(X,As))
However for starters, you should get familiar with loops.
You can do it using a simple for loop as follows. You basically loop through each value of a and plot the corresponding y function.
clear
clc
close all
x = -2:4;
%// Define a
a = -3:3;
%// Counter for legend
p = 1;
LegendText = cell(1,numel(a));
figure;
hold on %// Important to keep all the lines on the same plot.
for k = a
CurrColor = rand(1,3);
y= (2*k+1).*exp(-x)-(k+1).*exp(2.*x);
plot(x,y,'Color',CurrColor);
%// Text for legend
LegendText{p} = sprintf('a equals %d',k);
p = p+1;
end
legend(LegendText,'Location','best')
Which gives something like this:
You can customize the graph as you like. Hope that helps get you started!

Grouped boxplots in Matlab: a Generic function

After seeing this great post in SO:
Most efficient way of drawing grouped boxplot matlab
I was wondering if it is possible to create a function like that but a bit more generic, as in my application I need to make several analysis of different algorithms in different situations and it would be very tedious to tune the plotting code for each case.
I would like something generic for this kind of plots:
I coded a Matlab function that does that for you (me).
Features:
In each boxplot different amount of data supported
Any amount of groups and boxplot per group supported
Xlabel and boxplotlabel supported
Automatic choice of colors or user specified colors
Example of result of function:
CODE:
function multiple_boxplot(data,xlab,Mlab,colors)
% data is a cell matrix of MxL where in each element there is a array of N
% length. M is how many data for the same group, L, how many groups.
%
% Optional:
% xlab is a cell array of strings of length L with the names of each
% group
%
% Mlab is a cell array of strings of length M
%
% colors is a Mx4 matrix with normalized RGBA colors for each M.
% check that data is ok.
if ~iscell(data)
error('Input data is not even a cell array!');
end
% Get sizes
M=size(data,2);
L=size(data,1);
if nargin>=4
if size(colors,2)~=M
error('Wrong amount of colors!');
end
end
if nargin>=2
if length(xlab)~=L
error('Wrong amount of X labels given');
end
end
% Calculate the positions of the boxes
positions=1:0.25:M*L*0.25+1+0.25*L;
positions(1:M+1:end)=[];
% Extract data and label it in the group correctly
x=[];
group=[];
for ii=1:L
for jj=1:M
aux=data{ii,jj};
x=vertcat(x,aux(:));
group=vertcat(group,ones(size(aux(:)))*jj+(ii-1)*M);
end
end
% Plot it
boxplot(x,group, 'positions', positions);
% Set the Xlabels
aux=reshape(positions,M,[]);
labelpos = sum(aux,1)./M;
set(gca,'xtick',labelpos)
if nargin>=2
set(gca,'xticklabel',xlab);
else
idx=1:L;
set(gca,'xticklabel',strsplit(num2str(idx),' '));
end
% Get some colors
if nargin>=4
cmap=colors;
else
cmap = hsv(M);
cmap=vertcat(cmap,ones(1,M)*0.5);
end
color=repmat(cmap, 1, L);
% Apply colors
h = findobj(gca,'Tag','Box');
for jj=1:length(h)
patch(get(h(jj),'XData'),get(h(jj),'YData'),color(1:3,jj)','FaceAlpha',color(4,jj));
end
if nargin>=3
legend(fliplr(Mlab));
end
end
Simple example:
clear;clc;
% Create example data
A=rand(100,10);
B=rand(200,10);
C=rand(150,10);
% prepare data
data=cell(10,3);
for ii=1:size(data,1)
Ac{ii}=A(:,ii);
Bc{ii}=B(:,ii);
Cc{ii}=C(:,ii);
end
data=vertcat(Ac,Bc,Cc);
xlab={'Hey','this','works','pretty','nicely.','And','it','has','colors','!!!!'};
col=[102,255,255, 200;
51,153,255, 200;
0, 0, 255, 200];
col=col/255;
multiple_boxplot(data',xlab,{'A', 'B', 'C'},col')
title('Here it is!')
Mathworks file exchange file can be found here:
http://www.mathworks.com/matlabcentral/fileexchange/47233-multiple-boxplot-m

Distribution histogram

Hi i am trying to make a simple distribution histogram using some code from stack overflow
however i am unable to get it to work. i know that there are is a simple method for this using statistic toolbox but form a learning point of view i prefer a more explanatory code - can any one help me ?
%%
clear all
load('Mini Project 1.mat')
% Set data to var2
data = var2;
% Set the number of bins
nbins = 0:.8:8;
% Create a histogram plot of data sorted into (nbins) equally spaced bins
n = hist(data,nbins);
% Plot a bar chart with y values at each x value.
% Notice that the length(x) and length(y) have to be same.
bar(nbins,n);
MEAN = mean(data);
STD = sqrt(mean((data - MEAN).^2)); % can also use the simple std(data)
f = ( 1/(STD*sqrt(2*pi)) ) * exp(-0.5*((nbins-MEAN)/STD).^2 );
f = f*sum(nbins)/sum(f);
hold on;
% Plots a 2-D line plot(x,y) with the normal distribution,
% c = color cyan , Width of line = 2
plot (data,f, 'c', 'LineWidth', 2);
xlabel('');
ylabel('Firmness of apples after one month of storage')
title('Histogram compared to normal distribution');
hold of
You are confusing
hist
with
histc
Read up on both.
Also, you are not defining the number of bins, you are defining the bins themselves .
I don't have Matlab at hand now, but try the following:
If you want to compare a normal distribution to the bar plot bar(nbins,n), you should first normalize it:
bar(nbins,n/sum(n))
See if this solves your problem.
If not, try also removing the line f = f*sum(nbins)/sum(f);.