Using the built in Matlab function to run ANOVA on some data. I have groups of tests that I want to look at independently of the other tests, i.e. I want to run ANOVA on tests 1, 2 & 3, then 4, 5 & 6 and so on but when I look at 4, 5 & 6 the built in function always labels the x axis "1,2,3" as shown below.
How do I change the labels on the x axis to match the test number? (In the image below the x-axis reads 1,2,3 and not 4,5,6!) I have tried using "xticks" but that seems to just delete the autogenerated numbers and not add the numbers I want.
TIA
%Get data in
x = csvread('data.csv');
%single factor anova
[p,tbl,stats] = anova1(x(1:end,4:6));
title('Anova Tests 4, 5 & 6');
xlabel('Test Number');
ylabel('Load (N)');
ylim([0 50]);
Code/help for anova1 function: https://www.mathworks.com/help/stats/one-way-anova.html
The documentation states:
You can get some graphical assurance that the means are different by looking at the box plots. [...] For more information on this display, see boxplot.
Like most plot types in MATLAB, you can change the axis labels of a boxplot with xticklabels(). In this case:
xticklabels( [4 5 6] );
For robustness you could do
idx = 4:6;
[p,tbl,stats] = anova1(x(1:end,idx));
xticklabels( idx );
Related
I need to plot the divisory line together with the graph below:
The code I used to train the MLP neural network is here:
circles = [1 1; 2 1; 2 2; 2 3; 2 4; 3 2; 3 3; 4 1; 4 2; 4 3];
crosses = [1 2; 1 3; 1 4; 2 5; 3 4; 3 5; 4 4; 5 1; 5 2; 5 3];
net = feedforwardnet(3);
net = train(net, circles, crosses);
plot(circles(:, 1), circles(:, 2), 'ro');
hold on
plot(crosses(:, 1), crosses(:, 2), 'b+');
hold off;
But I'd like to show the line separating the groups in the chart too. How do I proceed? Thanks in advance.
First off, you're not training your neural network properly. You'd have to use both circles and crosses as input samples into your neural network and the output will have to be a two neuron output where [1 0] as the output would denote that the circles class is what the classification should be and [0 1] is what the crosses classification would be.
In addition, each column is an input sample while each row is a feature. Therefore, you have to transpose both of these and make a larger input matrix. You'll also need to make your output labels in accordance with what we just talked about:
X = [circles.' crosses.'];
Y = [[ones(1, size(circles,1)); zeros(1, size(circles,1))] ...
[zeros(1, size(crosses,1)); ones(1, size(crosses,1))]];
Now train your network:
net = feedforwardnet(3);
net = train(net, X, Y);
Now, if you want to figure out which class each point belongs to, you simply take the largest neuron output and whichever one gave you the largest, that's the class it belongs to.
Now, to answer your actual question, there's no direct way to show the "lines" of separation with Neural Networks if you use the MATLAB toolbox. However, you can show regions of separation and maybe throw in some transparency so that you can overlay this on top of the figure.
To do this, define a 2D grid of coordinates that span your two classes but with a finer grain... say... 0.01. Run this through the neural network, see what the maximum output neuron is, then mark this accordingly on your figure.
Something like this comes to mind:
%// Generate test data
[ptX,ptY] = meshgrid(1:0.01:5, 1:0.01:5);
Xtest = [ptX(:).'; ptY(:).'];
%// See what the output labels are
out = sim(net, Xtest);
[~,classes] = max(out,[],1);
%// Now plot the regions
figure;
hold on;
%// Plot the first class region
plot(Xtest(1, classes == 1), Xtest(2, classes == 1), 'y.');
%// Add transparency
alpha(0.1);
%// Plot the second class region
plot(Xtest(1, classes == 2), Xtest(2, classes == 2), 'g.');
%// Add transparency
alpha(0.1);
%// Now add the points
plot(circles(:, 1), circles(:, 2), 'ro');
plot(crosses(:, 1), crosses(:, 2), 'b+');
The first two lines of code generate a bunch of test (x,y) points and ensures that they're in a 2 row input matrix as that is what the network inputs require. I use meshgrid for generating these points. Next, we use sim to simulate or put in inputs into the neural network. Once we do this, we will have two output neuron neural network responses per input point where we take a look at which output neuron gave us the largest response. If the first output gave us the largest response, we consider the input as belonging to the first class. If not, then it's the second class. This is facilitated by using max and looking at each column independently - one column per input sample and seeing which location gave us the maximum.
Once we do this, we create a new figure and plot the points that belonged to class 1, which is the circles, in yellow and the second class, which is the crosses, in green. I throw in some transparency to make sure we can see the regions with the points. After, I plot the points as normal using your code.
With the above code, I get this figure:
As you can see, your model has some classification inaccuracies. Specifically, there are three crosses that would be misclassified as circles. You'll have to play around with number of neurons in the hidden layer as well as perhaps using a different activation function but this certainly is enough to get you started.
Good luck!
I cannot get Matlab to plot a a second time series to specific points along the x axis.
My data are two time series. Time series A is a 5 X 1 and time series B is a 7 X 1. I need A to plot on xticklabels 1-5. Then, with 'hold on', I need time series B to be shifted to the right to plot on xticklabels 6:12. I keep getting the second plot to plot directly over the first plot without the shift occurring. I've tried among other things -->
set(gca,'XTick',[6 7 8 9 10 11 12]);
and it displays x axis numbers shifting but the data does not plot in positions 6:12. Any help is much appreciated. I've seen some online answers but can't seem to get it correct.
In Matlab, you can plot something using plot(xArray, yArray);. If you want to shift the plot along the x axis, you could use plot(xArray + amountToShift, yArray);.
As I believe shifting is not what your real problem is, I've added an example where data gets plotted in the way you described:
A = [1, 2, 2, 1, 3];
tA = 1:5;
B = [3, 5, 2, 1, 2, 7, 5];
tB = 6:12;
plot(tA, A);
hold on;
plot(tB, B);
I have written a program that takes a lot of data and produces graphs.It would be really convenient and save me a lot of time if I could take curves on an existing figure and add their values together to make a single curve. For a simple example lets say I have the following code,
x = [0 1 2 3 4 5];
y = [0 1 2 3 4 5];
z = [4 6 2 8 7 9];
figure
plot(x,y,x,z)
This code will produce a figure with two curves. Without modifying the code or re-running the program, and only working with the figure options I would like to add the curve y + z to the plot. Is this possible? Thanks.
The reason I don't want to add the functionality is the plot code is buried within 8 loops
that calls data from a 4D cell array of file name strings.
If you have the x, y and z variable used in the plot you can just add new lines to the plot with
hold on
plot(x,y+z)
hold off
If you don't have them directly (they were generated in a function, for example, you can always get them from figure with XData, YData properties of line objects.
hline = findobj(gca,'type','line');
x = get(hline,'XData');
y = get(hline,'YData');
X = x{1}; % let's assume that all lines have the same x values.
Y = sum(cell2mat(y));
hold on
plot(X,Y)
hold off
I want to draw some plots in Matlab.
Details: For class 1, p(x|c1) is uniform for x between [2, 4] with the parameters a = 1 and b = 4. For class 2, p(x|c2) is exponential with parameter lambda = 1. Besides p(c1) = p(c2) = 0.5 I would like to draw a sketch of the two class densities multiplied by P(c1) and P(c2) respectively, as
a function of x, clearly showing the optimal decision boundary (or boundaries).
I have the solution for this problem, this is what the writer did (and I want to get), but there's no Matlab code, so I want to do it all by myself.
And this is what I drew.
And this is the MATLAB code I wrote.
x=0:1:8;
pc1 = 0.5;
px_given_c1 = exppdf(x,1);
px_given_c2 = unifpdf(x,2,4);
figure;
plot(x,px_given_c1,'g','linewidth',3);
hold on;
plot(x,px_given_c2,'r','linewidth',3);
axis([0 8 0 0.5]);
legend('P(x|c_1)','P(x|c_2)');
figure;
plot(x,px_given_c1.*pc1,'g','linewidth',3);
hold on;
plot(x,px_given_c2.*(1-pc1),'r','linewidth',3);
axis([0 8 0 0.5]);
legend('P(x|c_1)P(c_1)','P(x|c_2)P(c_2)');
As you can see, they are almost smiliar, but I am having problem with this uniform distribution, which is drawn in red. How can I change it?
You should probably change x=0:1:8; to something like x=0:1e-3:8; or even x=linspace(0,8,1000); to have finer plotting. This increases number of points in vectors (and therefore line segments) Matlab will use to plot.
Explanation: Matlab works with line segments when it does plotting!
By writing x=0:1:8; you create vector [0 1 2 3 4 5 6 7 8] that is of length 9, and by applying exppdf and unifpdf respectively you create two vectors of the same length derived from original vector. So basically you get vectors [exppdf(0) exppdf(1) ... exppdf(8)] and [unifpdf(0) unifpdf(1) ... unifpdf(8)].
When you issue plot command afterwards Matlab plots only line segments (8 of them in this case because there are 9 points):
from (x(1), px_given_c1(1)) to (x(2), px_given_c1(2)),
...
from (x(8), px_given_c1(8)) to (x(9), px_given_c1(9)).
I have a typical scenario in which there is a Vector X and Vector Y. Vector X contains increasing values, for example X = [1 1 1 2 2 3 4 4 4 4 4]. Vector Y contains real values of same size as X. Im looking to plot Index Vs Y with color change for each different value of X for the corresponding index.
For example, the plot should have color1 for the first 3 values of 1, color2 for the next 2 values of 2, color3 for 1 value 3 and so on.
Can any one help me
Building on Laurent's answer and implementing your "Index vs Y" requirement,
function color_plot(data_vector, color_vector)
styles={'ro','g.','bx','kd'};
hold off;
for i=unique(color_vector)
thisIdx=find(color_vector==i);
thisY=data_vector(color_vector==i);
thisStyle=styles{mod(i-1,numel(styles))+1};
plot(thisIdx,thisY,thisStyle);
hold on;
end
hold off;
My version also allows arbitrarily large color indices; if you don't have enough styles defined, it just wraps back around and reuses colors.
Update note I had to fix a sign above in the calculation oh thisStyle.
Testing it with
X = [1 1 1 2 2 3 4 4 4 4 4];
Y=rand(size(X))
color_plot(Y,X)
now gives
A plot() function option would be better (and maybe it exists).
Here's a workaround function to do this:
function colorPlot( data_vector, colors_vector)
%PLOTCOL plots data_vector with colors found in colors_vector
Styles=[{'r-'} {'g-'} {'b-'} {'k-'}];
last_off=0;
last_data=0;
for i=unique(colors_vector)
data_segment=data_vector(colors_vector==i);
len=length(data_segment);
if last_off==0
hold off;
plot( data_segment, 1:len,char(Styles(i)));
last_off=len;
else
plot([last_data data_segment],last_off:last_off+len,char(Styles(i)));
last_off=last_off+len;
end
last_data=data_segment(len);
hold on;
end
hold off;
end
Call it this way :
colorPlot(Y,X);