How to add a regression line to a scatter plot in MATLAB - matlab

I am trying to add a regression line onto a plot in MATLAB.
this is the code I have:
errorbar(x,y,SEM,'o')
hold on % Retains current plot while adding to it
scatter(x,y)
title('The Effect of Distance Between Images on the Flashed Face Distortion Effect','FontSize',14); % Adds title
xlabel('Distance (Pixels)','FontSize',12); % Adds label on the x axis
ylabel('Average Distortion Rating','FontSize',12); % Adds label on the y axis
hold off
And this is my code for a regression:
mdl = fitlm(x,y,'linear');
Could anyone tell me how to combine the two so i get the regression line on the plot?
I am using psychtoolbox on MATLAB on Windows.
Thanks!

Before the hold off statement, add the following lines:
xf = [min(x), max(x)];
plot(xf, polyval(polyfit(x,y,1), xf));
You may want to decorate your plot call with supplemental arguments setting the line style, and no additional toolboxes are required.

Related

How to update a plot with two subplot in MATLAB?

I have a function in MATLAB and it plots two curves and I run it two times.
On the first time plot main curve as you can see in the red color (first plot) and after that turn the "hold on" and execute my function again with the green color (second shape).
The problem is that the left subplot does not work and delete the first curve (red curve) but the second one works fine (last plot).
My main script is:
% some code to processing
...
roc('r.-',data); %this function plots my curves
and on the second run
% some code to processing
...
plot on
roc('g.-',data);
and my roc function contains:
%some code
...
subplot(1,2,1)
hold on
HCO1=plot(xroc(J),yroc(J),'bo');
hold off
legend([HR1,HRC1,HCO1],'ROC curve','Random classifier','Cut-off
point','Location','NorthOutside')
subplot(1,2,2)
hold on
HCO2=plot(1-xroc(J),yroc(J),'bo');
hold off
legend([HR2,HRC2,HCO2],'ROC curve','Random classifier','Cut-off
point','Location','NorthOutside')
disp(' ')
%....
Assuming your roc function calculates xroc and yroc I suggest you rewrite your code to modularize it
function [xroc,yroc] = roc(data)
%your algorithm or training code
%xroc=...
%yroc=...
end
this way your main script could be edited to something like this
%first run
[xroc1,yroc1] = roc(data);
%...some further processing with data variable
[xroc2,yroc2] = roc(data);
%plots
ax1 = subplot(1,2,1,'nextplot','add'); %create left axes
ax2 = subplot(1,2,2,'nextplot','add'); %create right axes (mirrored roc)
%now you can go ahead and make your plots
%first the not mirrored plots
plot(xroc1,yroc1,'r','parent',ax1);
plot(xroc2,yroc2,'g','parent',ax1);
%and then the mirrored plots
plot(1-xroc1,yroc1,'r','parent',ax2);
plot(1-xroc2,yroc2,'g','parent',ax2);
it is a little effort to rewrite but it surely will help to make your code scaleable to if you want to add more than just two curves in future.

Vertical lines for Bode plots in Matlab

I have graphed a Bode plot for my transfer function, and I was wondering if there is some way to insert either horizontal or vertical lines to show a specific value for the gain/phase angle or frequency?
I have found with the following code I can draw a horizontal line on the phase angle graph:
x = linspace(10^-1,10^2,100);
for bleh = 1:length(x)
y(bleh) = -30.9638;
end
bode(num, den)
hold on
plot(x,y)
But this does not seem to apply in the gain graph, nor does my limited knowledge (and only way that makes sense to me) of vertical lines. I tried:
y1 = get(gca,'ylim');
w1 = 1.2;
bode(num, den)
hold on
plot(x,y,[w1 w1],y1)
But I only get the one horizontal line as was done from the above code.
Is this a possibility?
(Using R2017a, if that matters.)
I'm not sure I've understood you question, nevertheless, I propose the following.
When there are more one axes in a figure, as it is the case of the bode diagram, if you want to add something in a specific axes (or in all) you have to specify, in the call to plot the handle of the axes.
So, to add lines in the bode diagram, you have first to identify the handles of the two axes: you can do it in, at least two way:
using the findobj function: ax=findobj(gcf,'type','axes')
extract them as the Children of the figure: ax=get(gcf,'children')
Once you have the handles of the axes, you can get their XLim and YLim that you can use to limit the extent of the line you want to add.
In the following example, I've used the above proposed approach to add two lines in each graph.
The horizontal and vertical lines are added in the middle point of the X and Y axes (problably this point does not have a relevant meaning, but it is ... just an example).
% Define a transfer function
H = tf([1 0.1 7.5],[1 0.12 9 0 0]);
% PLot the bode diagram
bode(H)
% Get the handles of the axes
ax=findobj(gcf,'type','axes')
phase_ax=ax(1)
mag_ax=ax(2)
% Get the X axis limits (it is the same for both the plot
ax_xlim=phase_ax.XLim
% Get the Y axis limits
phase_ylim=phase_ax.YLim
mag_ylim=mag_ax.YLim
%
% Define some points to be used in the plot
% middle point of the X and Y axes of the two plots
%
mid_x=(ax_xlim(1)+ax_xlim(2))/2
mid_phase_y=(phase_ylim(1)+phase_ylim(2))/2
mid_mag_y=(mag_ylim(1)+mag_ylim(2))/2
% Set hold to on to add the line
hold(phase_ax,'on')
% Add a vertical line in the Phase plot
plot(phase_ax,[mid_x mid_x],[phase_ylim(1) phase_ylim(2)])
% Add an horizontal line in the Phase plot
plot(phase_ax,[ax_xlim(1), ax_xlim(2)],[mid_phase_y mid_phase_y])
% Set hold to on to add the line
hold(mag_ax,'on')
% Add a vertical line in the Magnitide plot
plot(mag_ax,[mid_x mid_x],[mag_ylim(1) mag_ylim(2)])
% Add an Horizontal line in the Magnitide plot
plot(mag_ax,[ax_xlim(1), ax_xlim(2)],[mid_mag_y mid_mag_y])
Hope this helps,
Qapla'

Matlab logarithmic range colorbar imagesc

Using the function imagesc in Matlab, I plot my (X,Y, Z) data-X array distance, Y array time, and my data Z = Z(X,Y) a matrix.
I notice that the 80% of the image has one color, because the change of Z data occurred only in the end of X for almost all Y.
Right now I use colormap('hsv') which give I think the largest range of different colors.
I need to change the colorbar range to a logarithmic one to improve visual the range of the change of my output data through time along the distance X.
I have used also contourf but still I am not sure if it will better to use this function and not imagesc which the output is more smoothed.
Please, any idea, any method or any small script that I could use to show visual the difference in data in logarithmic scale in 2D using imagesc or another build in function is more than welcome!
thank you
There is a discussion at the Mathworks website where someone provided a function that does logarithmic color bars.
https://www.mathworks.com/matlabcentral/newsreader/view_thread/152310
EDIT: copying and pasting code from link
function cbar = colorbar_log(my_clim)
%COLORBAR_LOG Apply log10 scaling to pseudocolor axis
% and display colorbar COLORBAR_LOG(V), where V is the
% two element vector [cmin cmax], sets manual, logarithmic
% scaling of pseudocolor for the SURFACE and PATCH
% objects. cmin and cmax should be specified on a LINEAR
% scale, and are assigned to the first and last colors in
% the current colormap. A logarithmic scale is computed,
% then applied, and a colorbar is appended to the current
% axis.
%
% Written by Matthew Crema - 7/2007
% Trick MATLAB by first applying pseudocolor axis
% on a linear scale
caxis(my_clim)
% Create a colorbar with log scale
cbar = colorbar('Yscale', 'log');
% Now change the pseudocolor axis to a log scale.
caxis(log10(my_clim));
% Do not issue the COLORBAR command again! If you want to
% change things, issue COLORBAR_LOG again.

Matlab scatter plot with straight lines connecting the points

Is there an easy command to have a plot like the blue line in the picture (excel)? Matlab defaults to produce something like the line in red. The only way I know to do this is to issue a plot command for each segment of the line:
for i=2:n-1
plot([data(i-1,1) data(i,1)],[data(i-1,2) data(i,2)],'-b'); hold on;
end
You can just plot the entire array and let plot automatically draw straight line segments between each of the points. This is the default behaviour when plotting things in MATLAB. MATLAB plotting smooth lines is not the default behaviour when the plot is produced, so I'm not sure where you're getting that information.
You would need to perform some sort of spline interpolation to get the red line, but you desire the blue curve and so plotting the entire array in a single plot command should suffice.
It's as simple as:
plot(data(:,1), data(:,2), '-b');
Just to be sure that we're on the same page, I'm going to reproduce your data then use the above command to plot the data so you can see for yourself that the behaviour you desire is achieved:
data = [0 0; 1 1; 2 4; 3 6; 4 4]; %// Your data reconstructed
plot(data(:,1), data(:,2), '-b'); %// Main plotting code
%// Some extras
xlim([0 4.5]);
ylim([0 7]);
grid;
I've added in some extra code to get the plot to look like your example. I've made the x-axis limits go up to 4.5 and the y-axis limits go up to 7. I've also placed a grid in the plot.
We get:

Matlab: Plot3 not showing the 3rd axis

All the three variables I am using to plot are matrix of size 1x1x100. I am using this code line to plot:
hold on;
for i=1:100
plot3(R_L(:,:,i),N_Pc(:,:,i),CO2_molefraction_top_of_window(:,:,i),'o');
xlabel('R_L');
ylabel('N_P_c');
zlabel('CO_2')
end
However, I am not getting the third axis, and hence the third variable CO2_molefraction_top_of_window on the plot. May I know where am I wrong?
Besides the above question, but on the same subject, I want to know if there is any option where I can plot 4 dimensional plot just like the 3 dimensional plot which can be drawn using plot3?
So I had the same problem when using plot3. For some reason, using the hold on command "flattens" the plot. I'm not sure why, but I suspect it has something to do with the operation hold on performs on the plot.
Edit: To clarify, the 3d plot is still there, but the perspective has been forced to change. If you use the "rotate 3D" tool (the one with an arrow around a cube), you can see the graph is 3d, the default perspective is just straight on so only two axes are visible and it appears flat.
Just a note --- you only need to do the xlabel ylabel zlabel commands once (outside the loop).
Also:
is there any reason your matrices are 1x1x100 instead of just 100x1 or 1x100?
Because if you reshape them to 2D you can just do the plotting in one hit.
What do you mean by "missing third axis"? When I run your code (or as close as I can get, since you didn't provide a reproducible example), I do get a 3rd axis:
.
X = rand(1,1,100); % 1x1x100 X matrix
Y = rand(1,1,100); % 1x1x100 Y matrix
Z = rand(1,1,100); % 1x1x100 Z matrix
% Now, we could do a for loop and plot X(:,:,i), Y(:,:,i), Z(:,:,i),
% OR we can just convert the matrix to a vector (since it's 1x1x100 anyway)
% and do the plotting in one go using 'squeeze' (see 'help squeeze').
% squeeze(X) converts it from 1x1x100 (3D matrix) to 100x1 (vector):
plot3(squeeze(X),squeeze(Y),squeeze(Z),'o')
xlabel('x')
ylabel('y')
zlabel('z')
This gives the following, in which you can clearly see three axes:
If it's the gridlines that you want to make the graph look "more 3D", then try grid on (which is in the examples in the Matlab help file for plot3, try help plot3 from the Matlab prompt):
grid on
You will have to clarify "missing third axis" a bit more.
I came across a similar problem and as #Drofdarb's the hold on seems to flatten out one axis. Here is a snippet of my code, hope this helps.
for iter = 1:num_iters:
% hold on;
grid on;
plot3(tita0,tita1, num_iters,'o')
title('Tita0, Tita1')
xlabel('Tita0')
ylabel('Tita1')
zlabel('Iterations')
hold on; % <---- Place here
drawnow
end
As opposed to:
for iter = 1:num_iters:
grid on;
hold on; % <---- Not here
plot3(tita0,tita1, num_iters,'o')
title('Tita0, Tita1')
xlabel('Tita0')
ylabel('Tita1')
zlabel('Iterations')
% hold on;
drawnow
end