Errorbar line missing in Matlab - matlab

The following code produces the image shown:
probabilities = datasetlist(1,:);
avgscores = datasetlist(2,:);
x = probabilities;
y = probabilities;
err = avgscores;
hold on
for k = 1:length(x)
e1 = errorbar(x(k),y(k),err(k),'-');
if err(k) == min(err)
set(e1,'Color','r')
set(e1,'MarkerEdgeColor','r')
set(e1,'Marker','*')
else
set(e1,'Color','k')
set(e1,'MarkerEdgeColor','k')
set(e1,'Marker','.')
end
end
hold on
e1.LineStyle = '-';
But, there should be a line connecting the datapoints. I even set the e1.LineStyle, but that didn't work. How can I produce that line?

You have no line because you don't plot vectors, but single values each time, which is why you get something that is closer to a scatter plot.
Below are two of the ways to fix this:
Solution 1 is a workaround that changes your existing code minimally.
Solution 2 is much shorter code that achieves a same-looking result, by plotting vectors directly. (recommended).
function q40765062
%% Prepare the data:
datasetlist = [0.4:0.05:0.7; abs(randn(1,7))];
probabilities = datasetlist(1,:);
avgscores = datasetlist(2,:);
x = probabilities;
y = probabilities;
err = avgscores;
%% Solution 1:
figure();
hold on
for k = 1:length(x)
e1 = errorbar(x(k),y(k),err(k),'-');
if err(k) == min(err)
set(e1,'Color','r')
set(e1,'MarkerEdgeColor','r')
set(e1,'Marker','*')
else
set(e1,'Color','k')
set(e1,'MarkerEdgeColor','k')
set(e1,'Marker','.')
end
end
plot(x,y,'-k'); % < The main difference in this solution.
%% Solution 2:
figure();
[~,I] = min(err); % < We compute the index of the minimal value before plotting anything.
errorbar(x,y,err,'-*k'); hold on; % < Notice how we use the entire vectors at the same time.
errorbar(x(I),y(I),err(I),'-*r'); % < We only plot one value this time; in red.

Related

How can I generate CDF from a large dataset in MATLAB?

I have 6 datasets each containing 10000 entries.
I want to plot their CDFs for comparison.
In MATLAB I am using the following code:
figure()
ksdensity(dataset1,'Support','positive','Function','cdf',...
'NumPoints',5)
xlabel('Error')
ylabel('CDF')
But I am not sure, is it the right way or wrong?
How can I do that?
I am getting the following figure.
Update:
This has been made even easier with cdfplot().
% MATLAB R2019a
% Example Data
X = wblrnd(2,3,50000,1);
Y = wblrnd(3,2,50000,1);
Z = wblrnd(2.5,2.5,50000,1);
Data = [X Y Z];
figure, hold on
for k = 1:size(Data,2)
h(k) = cdfplot(Data(:,k));
end
legend('show')
It looks like you've got the result you want except for the legend and markers. If you'd like more control of the plotting features, I'd suggest obtaining the necessary elements to plot from ksdensity using [f,xi] = ksdensity(x) then plotting separately.
% MATLAB R2019a
% Example Data
X = wblrnd(2,3,50000,1);
Y = wblrnd(3,2,50000,1);
Z = wblrnd(2.5,2.5,50000,1);
Data = [X Y Z];
NumPointCDF = 5; % Number of points to estimate CDF with
figure, hold on
for ii = 1:size(Data,2) % for each column of Data
[fii, xii] = ksdensity(Data(:,ii),'Support','positive','Function','cdf',...
'NumPoints',NumPointsCDF);
p(ii) = plot(xii,fii,'LineWidth',1.1,'Marker','.','MarkerSize',12);
end
legend('X','Y','Z')
Alternatively, you could just plot each first,
figure, hold on
for ii = 1:size(Data,2) % for each column of Data
[fii, xii] = ksdensity(Data(:,ii),'Support','positive','Function','cdf',...
'NumPoints',NumPointsCDF);
p(ii) = plot(xii,fii);
end
and then change the properties of each line later with p(1).foo (see here).
For example, one at a time: p(1).Marker = 's' % square
Or all at once:
% Update all properties using the object
for ii = 1:size(Data,2)
p(ii).Marker = '.'; % Adjust specific properties of p(ii) as needed
p(ii).LineWidth = 1.2;
end
Reference:
Graphics Object Properties
Access Property Values

Two plots of same wave in MatLab, but plot created after transforming to polar coordinates is distorded?

I have created some MatLab code that plots a plane wave using two different expressions that give the same plane wave. The first expression is in Cartesian coordinates and works fine. However, the second expression is in polar coordinates and when I calculate the plane wave in this case, the plot is distorted. Both plots should look the same. So what am I doing wrong in transforming to/from polar coordinates?
function Plot_Plane_wave()
clc
clear all
close all
%% Step 0. Input paramaters and derived parameters.
alpha = 0*pi/4; % angle of incidence
k = 1; % wavenumber
wavelength = 2*pi/k; % wavelength
%% Step 1. Define various equivalent versions of the incident wave.
f_u_inc_1 = #(alpha,x,y) exp(1i*k*(x*cos(alpha)+y*sin(alpha)));
f_u_inc_2 = #(alpha,r,theta) exp(1i*k*r*cos(theta-alpha));
%% Step 2. Evaluate the incident wave on a grid.
% Grid for field
gridMax = 10;
gridN = 2^3;
g1 = linspace(-gridMax, gridMax, gridN);
g2 = g1;
[x,y] = meshgrid(g1, g2);
[theta,r] = cart2pol(x,y);
u_inc_1 = f_u_inc_1(alpha,x,y);
u_inc_2 = 0*x;
for ir=1:gridN
rVal = r(ir);
for itheta=1:gridN
thetaVal = theta(itheta);
u_inc_2(ir,itheta) = f_u_inc_2(alpha,rVal,thetaVal);
end
end
%% Step 3. Plot the incident wave.
figure(1);
subplot(2,2,1)
imagesc(g1(1,:), g1(1,:), real(u_inc_1));
hGCA = gca; set(hGCA, 'YDir', 'normal');
subplot(2,2,2)
imagesc(g1(1,:), g1(1,:), real(u_inc_2));
hGCA = gca; set(hGCA, 'YDir', 'normal');
end
Your mistake is that your loop is only going through the first gridN values of r and theta. Instead you want to step through the indices of ix and iy and pull out the rVal and thetaVal of the matrices r and theta.
You can change your loop to
for ix=1:gridN
for iy=1:gridN
rVal = r(ix,iy); % Was equivalent to r(ix) outside inner loop
thetaVal = theta(ix,iy); % Was equivalent to theta(iy)
u_inc_2(ix,iy) = f_u_inc_2(alpha,rVal,thetaVal);
end
end
which gives the expected graphs.
Alternatively you can simplify your code by feeding matrices in to your inline functions. To do this you would have to use an elementwise product .* instead of a matrix multiplication * in f_u_inc_2:
alpha = 0*pi/4;
k = 1;
wavelength = 2*pi/k;
f_1 = #(alpha,x,y) exp(1i*k*(x*cos(alpha)+y*sin(alpha)));
f_2 = #(alpha,r,theta) exp(1i*k*r.*cos(theta-alpha));
% Change v
f_old = #(alpha,r,theta) exp(1i*k*r *cos(theta-alpha));
gridMax = 10;
gridN = 2^3;
[x,y] = meshgrid(linspace(-gridMax, gridMax, gridN));
[theta,r] = cart2pol(x,y);
subplot(1,3,1)
contourf(x,y,real(f_1(alpha,x,y)));
title 'Cartesian'
subplot(1,3,2)
contourf(x,y,real(f_2(alpha,r,theta)));
title 'Polar'
subplot(1,3,3)
contourf(x,y,real(f_old(alpha,r,theta)));
title 'Wrong'

Visualizing matrix values in real time

Suppose I have a 5x5 matrix.
The elements of the matrix change (are refreshed) every second.
I would like to be able to display the matrix (not as a colormap but with the actual values in a grid) in realtime and watch the values in it change as time progresses.
How would I go about doing so in MATLAB?
A combination of clc and disp is the easiest approach (as answered by Tim), here's a "prettier" approach you might fancy, depending on your needs. This is not going to be as quick, but you might find some benefits, such as not having to clear the command window or being able to colour-code and save the figs.
Using dispMatrixInFig (code at the bottom of this answer) you can view the matrix in a figure window (or unique figure windows) at each stage.
Example test code:
fig = figure;
% Loop 10 times, pausing for 1sec each loop, display matrix
for i=1:10
A = rand(5, 5);
dispMatrixInFig(A,fig)
pause(1)
end
Output for one iteration:
Commented function code:
function dispMatrixInFig(A, fig, strstyle, figname)
%% Given a figure "fig" and a matrix "A", the matrix is displayed in the
% figure. If no figure is supplied then a new one is created.
%
% strstyle is optional to specify the string display of each value, for
% details see SPRINTF. Default is 4d.p. Can set to default by passing '' or
% no argument.
%
% figname will appear in the title bar of the figure.
if nargin < 2
fig = figure;
else
clf(fig);
end
if nargin < 3 || strcmp(strstyle, '')
strstyle = '%3.4f';
end
if nargin < 4
figname = '';
end
% Get size of matrix
[m,n] = size(A);
% Turn axes off, set origin to top left
axis off;
axis ij;
set(fig,'DefaultTextFontName','courier', ...
'DefaultTextHorizontalAlignment','left', ...
'DefaultTextVerticalAlignment','bottom', ...
'DefaultTextClipping','on');
fig.Name = figname;
axis([1, m-1, 1, n]);
drawnow
tmp = text(.5,.5,'t');
% height and width of character
ext = get(tmp, 'Extent');
dy = ext(4);
wch = ext(3);
dwc = 2*wch;
dx = 8*wch + dwc;
% set matrix values to fig positions
x = 1;
for i = 1:n
y = 0.5 + dy/2;
for j = 1:m
y = y + 1;
text(x,y,sprintf(strstyle,A(j,i)));
end
x = x + dx;
end
% Tidy up display
axis([1-dwc/2 1+n*dx-dwc/2 1 m+1]);
set(gca, 'YTick', [], 'XTickLabel',[],'Visible','on');
set(gca,'XTick',(1-dwc/2):dx:x);
set(gca,'XGrid','on','GridLineStyle','-');
end
I would have thought you could achieve this with disp:
for i=1:10
A = rand(5, 5);
disp(A);
end
If you mean that you don't want repeated outputs on top of each other in the console, you could include a clc to clear the console before each disp call:
for i=1:10
A = rand(5, 5);
clc;
disp(A);
end
If you want to display your matrix on a figure it is quite easy. Just make a dump matrix and display it. Then use text function to display your matrix on the figure. For example
randMatrix=rand(5);
figure,imagesc(ones(20));axis image;
hold on;text(2,10,num2str(randMatrix))
If you want to do it in a for loop and see the numbers change, try this:
for i=1:100;
randMatrix=rand(5);
figure(1),clf
imagesc(ones(20));axis image;
hold on;text(2,10,num2str(randMatrix));
drawnow;
end

How to plot a matlab function for different parameters using hold on command

I have a matlab function that contain some constant parameter, I want to draw that function, on say same figure, using hold on (probably) while changing the value of that constant.
This my code:
close all
clear all
clc
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y)
m = 10;
figure(h1);
hold on
plot(x,y,': r')
When I tried using this code, I got two lines coincident on each others; and it looks matlab just used last value for the parameter m how can I make it use different values.
I found some stuff here, but doesn't fulfill my needs.
Any suggestions?
You need to recalculate y as well:
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y); hold on;
m = 10;
y = m*x + 10;
figure(h1);
plot(x,y,': r')
Or create an anonymous function:
x = 1:1:10;
f = #(m) m*x + 10;
%// and then:
h1 = figure;
plot(x,f(5) ); hold on;
plot(x,f(10),': r');
Currently, you're only updating m but you also have to calculate y again. This is why it plots exactly the same y (i.e. m is still 5) function when you issue the second plot.
You might want to use a simple for loop for that, like:
m = 5;
x = 1:1:10;
figure;
hold on;
for m=1:1:10
y = m*x + 10;
plot(x,y,': r')
end
In addition to the short answer - improving the plot..
%% Data Preparations
x = 1:10;
ms = 3; % number of different slopes
%% Graph Preparations
hold on;
% Prepare the string cell array
s = cell(1, ms);
% Handle storage
h = zeros(1, ms);
% Plot graphs
for m=1:ms
y = m*x + 10;
h(m)= plot(x,y,'Color',[1/m rand() rand()]);
s{m} = sprintf('Plot of y(m=%d)', m);
end
% Plot all or select the plots to include in the legend
ind = [ms:-1:1] .* ones(1,ms); % plot all
%ind = [ 1 3 4 ]; % plot selected
% Create legend for the selected plots
legend(h(ind), s{ind});
Additional advice: When working with MATLAB and you try to improve the performance of your code, you shoud try to avoid using for-loops since MATLAB is MATrix manipulation and that's what it can do best. Ones you've taken this philosophy in, you'll create the most beautiful code one-liners! ;)
This script is an adoption of Steve Lord's post.

Matlab plot in loop error

I am creating figures in a for loop. The figure is a 2D mesh plot, which is supposed to be updated every iteration. The value to be plotted in a 200x200 array.
My problem is: It seems the calculation is running every iteration, but the plot is always the first one created, no matter I just plot or save to file.
Here is my code:
x = 1:200;
y = x;
for i = 1:100000
c = calculate(stuff, c); % value to be created, nothing to do with x and y
h = figure;
mesh(x,y,c);
saveas(h, sprintf('FIG%d.jpg',i);
drawnow; % did not work with or without this command
close(h);
end
First, thank you for all your inputs and suggestions! I didn't expect to get so many help within such a short time!
Then, I can answer some of the confusions here.
To Daniel: yes the c is changing. The program is calculating c based on its previous value. And there is sufficient step for c to change.
To R.Schifini: I tried pause(.1) but it didn't help unfortunately
To Andrew: thanks for pointing it. The complete program is attached now. And as to Daniel, the program calculate the value of c based on its previous values.
To The-Duck: I tried clf(h, 'reset') but unfortunately it didn't help.
Complete code:
Main program: please refer to wikipedia for the physical equation if you are interested
http://en.wikipedia.org/wiki/Cahn%E2%80%93Hilliard_equation
% Program to calculate composition evolution for nucleation and growth
% by solving Cahn-Hilliard equation - Time dependent non-linear
% differential equation
% Parameter
sig = 0.1; % J/m^2
delta = 10E-9; % m
D = 1E-9; %m^2/s
A = 10*sig/delta; % J/m
K = 3*sig*delta; % J/m^3
M = D/(2*A); % m^2/s
N = 200; % mesh size
dt = 1E-12; %s
h = delta/10;
% Rng control
r = -1+2.*rand(N);
beta = 1E-3;
n = 10000;
% initialization
c0 = zeros(200);
c0 = c0+ 0.1+beta.*r;
c = c0;
x = h.*linspace(-N/2,N/2,N);
y=x;
% Iteration
for i = 1:n
LP_c = laplacian(c,h);
d_f = A*(4*(c.^3)-6*(c.^2)+2*c);
sub = d_f - (2*K)*LP_c;
LP_RHS = laplacian(sub,h);
RHS = M*LP_RHS;
c = c + dt.*RHS;
% Save image every 2000 steps
% if ( i==1000 || i==10000 || i==100000)
% h = mesh(x,y,c);
% pause(.1);
% saveas(h, sprintf('FIG%d.jpg',i));
% clf(h,'reset');
% end
end
%h = figure;
mesh(x,y,c);
Laplacian function:
function LP_c = laplacian(c,h)
v1 = circshift(c,[0 -1]);
v2 = circshift(c,[0 1]);
v3 = circshift(c,[-1 0]);
v4 = circshift(c,[1 0]);
LP_c = (v1+v2+v3+v4-4.*c)./(h^2);
end
Result:
You can see the commented part in main program is for plotting periodically. They all give the same plots for each iteration. I tried the current OR version, also tried if ( mod(i,2000) == 0) to plot more pics. There is no difference. Shown:
However, if I comment out the periodic plotting, just run the program for different values of n, I got different plots, and they obey physical laws (evolving structure), shown in time order
Therefore I excluded the possibility that c might not update itself. It has to be some misuse of the plotting function of matlab. Or maybe some memory issue?
An interesting point I discovered during edition session: If I put the command h = figure in front of the loop and plot after the loop end, like this:
h = figure;
% Iteration
for i = 1:n
LP_c = laplacian(c,h);
d_f = A*(4*(c.^3)-6*(c.^2)+2*c);
sub = d_f - (2*K)*LP_c;
LP_RHS = laplacian(sub,h);
RHS = M*LP_RHS;
c = c + dt.*RHS;
end
mesh(x,y,c);
It seems all value of c calculated during the loop will overlap and give a figure shown below: I guess this indicates some facts about the plotting function of matlab, but I am not sure
Btw, can I answer directly to each comment and high light the new added section in my post? Sorry I am not as familiar with Stack Overlow as I should have :)
I ran your routine and with the following changes it works for me:
% Iteration
for i = 1:n
LP_c = laplacian(c,h);
d_f = A*(4*(c.^3)-6*(c.^2)+2*c);
sub = d_f - (2*K)*LP_c;
LP_RHS = laplacian(sub,h);
RHS = M*LP_RHS;
c = c + dt.*RHS;
% Save image every 2000 steps
if ( mod(i,2000)==0)
h1 = mesh(x,y,c);
drawnow;
saveas(h1, sprintf('FIG%d.jpg',i));
end
end
The main change is the figure handle variable from h to h1. Why? You are already using variable h in your equations.
Regards,