How to draw over a imagesc image in Matlab - matlab

I have a function:
A = [5,16,18,4,9;
9,10,14,3,18;
2,7,9,11,21;
3,7,2,19,22;
4,9,10,13,8]
figure
colormap(gray)
imagesc(ones(15,15))
axis off
for t = 1:15
for k = 1:15
text(t, k, sprintf('%c', A(t,k) + 96))
end
end
And I want to draw a line between one position and another say from (1,2) to (4,5) how can I achieve this, I think I can use either the plot or line functions but am not sure how to use them.

If I didn't get anything wrong:
A = [5,16,18,4,9;
9,10,14,3,18;
2,7,9,11,21;
3,7,2,19,22;
4,9,10,13,8]
figure
colormap(gray)
imagesc(ones(5,5))
axis off
for t = 1:5
for k = 1:5
text(t, k, sprintf('%c', A(t,k) + 96))
end
end
hold on;
line([1 2], [4 5]);
Result:

Related

How to plot multiple lines in one plot and save them

Question 1 SOLVED
I am working on the following simulation:
x = [8 9 7 6 5];`
if isvector(x)
for i=1:length(x)
% simulation gives me a matrix y,t,z, (c by 5)
% where size(y,1)=size(z,1)=size(t,1)= lenght(x)=5
% size(y,2)=c
% a plot will collect all lines:
% for x=8 there are 3 lines ( the first row of each matrix `y`, `t`, `z`
% for x=9 there are 3 lines ( the second row of each matrix `y`, `t`, `z`
% ...
% for x=5 there are 3 lines ( the 5th row of each matrix `y`, `t`, `z`
end
end
Let me show an example:
y = rand(5,8)
t = rand(5,8)
z = rand(5,8)
To plot I have started with:
% I was using the initial loop:
if isvector(x)
for i=1:length(x)
% simulation gives me a matrix y,t,z, (c by 5)
%% plots
h(1)=figure;
plot (c,y(i,:));
grid on;
hold on;
plot (c,t(i,:));
plot (c,z(i,:));
hold off;
end
end
As a result, MATLAB gives me 3 figures, but I have expected only one figure with multiple lines. I start from the inside of the initial loop and create a new loop, but it doesn't help me. How to fix it? How to plot all lines (in this example, all 15 lines (#x(i) = 5, #array = 3))?
If you need that loop for further analysis, just move the figure() outside the loop. Otherwise, you could also plot all lines from a single plot() call:
x = [8 9 7 6 5];
c = 1:8;
y = rand(5, 8);
t = rand(5, 8);
z = rand(5, 8);
% Loop approach, move figure() outside the loop
if isvector(x)
figure(1);
hold on;
for i = 1:length(x)
plot(c, y(i, :));
plot(c, t(i, :));
plot(c, z(i, :));
end
hold off;
grid on;
end
% Plot everything with one plot() call
if isvector(x)
figure(2);
plot(c, [y; t; z]);
grid on;
end
The outputs are the same except for the lines' color, which is due to the order of the plotting (first line of y, t, z, second line of ..., and so on vs. all lines from y, all lines from t, and so on.
Hope that helps!
EDIT: To plot all three lines for each x(i) in separate figures, you could use this loop approach:
x = [8 9 7 6 5];
c = 1:8;
y = rand(5, 8);
t = rand(5, 8);
z = rand(5, 8);
if isvector(x)
for i = 1:length(x)
figure(i);
hold on;
plot(c, y(i, :));
plot(c, t(i, :));
plot(c, z(i, :));
hold off;
grid on;
end
end

matlab: how do I do animated plot in a figure of two subplot

There is example of the web that shows how to do animated plot in a single figure.
However, I want to do two subplots in a single figure, such that they will show animation in a first subplot, and then the animation ina second subplot.
Using 'figure(1)' or 'figure (2)' and 'hold on', I can do the animation plot as follows. However, How do I call the subplot to do the similiar things?
So the effect I am looking for is: 1) figure that is opened and has two subplot. 2) plot the animated curve in the 1st subplot, then plot the animated curve in the 2nd subplot. 3) I want to go back to the 1st subplot to plot more things, and also go to 2nd subplot to plot more things.
figure(1); hold on; x = 1:1000;
y = x.^2;
%// Plot starts here
figure,hold on
%// Set x and y limits of the plot
xlim([min(x(:)) max(x(:))])
ylim([min(y(:)) max(y(:))])
%// Plot point by point
for k = 1:numel(x)
plot(x(k),y(k),'-') %// Choose your own marker here
%// MATLAB pauses for 0.001 sec before moving on to execue the next
%%// instruction and thus creating animation effect
pause(0.001);
end
Just do the subplot's in the loop:
for k = 1:numel(x)
subplot(1,2,1)
plot(x(k),y(k),'-') %// Choose your own marker here
subplot(1,2,2)
plot(x(1:k),y(1:k))
%// MATLAB pauses for 0.001 sec before moving on to execue the next
%%// instruction and thus creating animation effect
pause(0.001);
end
% Easiest way
x = rand(1, 11); y = rand(1, 11);
z = rand(1, 11); a = rand(1, 11);
figure
for i = 1 : 10
subplot(211)
plot(x(i : i+1), y(i : i+1), '.-k');
hold on; % include this if you want to show plot history
subplot(212)
plot(z(i : i+1), a(i : i+1), '.-k');
drawnow;
pause(0.1);
end
% If you don't want to call "plot" interatively
x = rand(1, 11); y = rand(1, 11);
z = rand(1, 11); a = rand(1, 11);
figure
subplot(211)
p1 = plot(NaN, NaN, 'marker', 'o');
subplot(212)
p2 = plot(NaN, NaN, 'marker', 'd');
for i = 1 : 10
set(p1, 'xdata', x(i : i+1), 'ydata', y(i : i+1));
set(p2, 'xdata', z(i : i+1), 'ydata', a(i : i+1));
drawnow;
pause(0.1);
end
First define your plot as a construct, so p1 = plot(x,y). Then you set up your loop and in the loop your write
set(p1,'YData',y);
This will update the plot p1s YData which is y. If you want to see it in an animated form just add a pause(0.1) %seconds after the set.

Draw log graph curve on Matlab by clicking?

I'd like to draw a curve on an empty (semilog-y) graph by clicking the points I want it to run through, on the X-Y plane.
Is there a function for this?
edit: I'm trying to do this by obtaining the position of last pointer click -
axis([0 3000 0 1000]);
co=get(gcf, 'CurrentPoint');
It seems to return the cursor position at the time of execution, but it does not change later.
edit2: Here's what works for me. The actual drawing I can do by using the arrays of points collected.
clear
clc
h=plot(0);
grid on;
xlim([0 3000]);
ylim([0 1000]);
datacursormode on;
% Enlarge figure to full screen.
screenSize = get(0,'ScreenSize');
set(gcf, 'units','pixels','outerposition', screenSize);
hold on;
% Print the x,y coordinates - will be in plot coordinates
x=zeros(1,10); y=zeros(1,10);
for p=1:10;
[x(p),y(p)] = ginput(1) ;
% Mark where they clicked with a cross.
plot(x(p),y(p), 'r+', 'MarkerSize', 20, 'LineWidth', 3);
% Print coordinates on the plot.
label = sprintf('(%.1f, %.1f)', x(p), y(p));
text(x(p)+20, y(p), label);
end
Not really, but now there is:
function topLevel
%// parameters
xrange = [0 100];
yrange = [1e-4 1e4];
%// initialize figure, plot
figure, clf, hold on
plot(NaN, NaN);
axis([xrange yrange]);
set(gca, 'YScale', 'log')
t = text(sum(xrange)/2, sum(yrange)/2, ...
'<< Need at least 3 points >>',...
'HorizontalAlignment', 'center');
%// Main loop
xs = []; p = [];
ys = []; P = [];
while true
%// Get new user-input, and collect all of them in a list
[x,y] = ginput(1);
xs = [xs; x]; %#ok<AGROW>
ys = [ys; y]; %#ok<AGROW>
%// Plot the selected points
if ishandle(p)
delete(p); end
p = plot(xs, ys, 'rx');
axis([xrange yrange]);
%// Fit curve through user-injected points
if numel(xs) >= 3
if ishandle(t)
delete(t); end
%// Get parameters of best-fit in a least-squares sense
[A,B,C] = fitExponential(xs,ys);
%// Plot the new curve
xp = linspace(xrange(1), xrange(end), 100);
yp = A + B*exp(C*xp);
if ishandle(P)
delete(P); end
P = plot(xp,yp, 'b');
end
end
%// Fit a model of the form y = A + B·exp(C·x) to data [x,y]
function [A, B, C] = fitExponential(x,y)
options = optimset(...
'maxfunevals', inf);
A = fminsearch(#lsq, 0, options);
[~,B,C] = lsq(A);
function [val, B,C] = lsq(A)
params = [ones(size(x(:))) x(:)] \ log(abs(y-A));
B = exp(params(1));
C = params(2);
val = sum((y - A - B*exp(C*x)).^2);
end
end
end
Note that as always, fitting an exponential curve can be tricky; the square of the difference between model and data is exponentially much greater for higher data values than for lower data values, so there will be a strong bias to fit the higher values better than the lower ones.
I just assumed a simple model and used a simple solution, but this gives a biased curve which might not be "optimal" in the sense that you need it to be. Any decent solution really depends on what you want specifically, and I'll leave that up to you ^_^

Plotting of a expotential curve between an interval in MATLAB

I would like to plot an expotential curve between an interval based on a different multipler for each interval.
I have tried this:
%Plotting of h curve
function PlotQ(Time,h)
for i=2:size(Time,1)
for t=Time(i-1):0.1:Time(i)
plot([Time(i-1), Time(i)],exp(-h(i)*t))
hold on;
end
end
ymax = max();
xlim([1 max(Time)]);
ylim([-0.5 ymax+0.5]);
xlabel('Time')
ylabel('Rate')
end
The curve comes out like this:
Not sure what I am doing wrong.. Need some guidance..
New Edit:
T =[0;0.569444444444444;1.06666666666667;2.08611111111111;3.09722222222222;4.11111111111111;5.12500000000000;7.16111111111111;10.2000000000000;20.3444444444444;30.4944444444444];
%Plotting of h and Q
h = [0;0.0187;0.0194;0.0198;0.0215;0.0225;0.0241;0.0316;0.0379;0.0437;0.0452];
PlotQ(Time,h)
If I understood correctly, You are looking for something like this.
%Plotting of h curve
function PlotQ(Time,h)
for i=2:size(Time,1)
tVector=Time(i-1):0.1:Time(i);
sizetVector=length(tVector);
for t=2:sizetVector
plot([tVector(t-1), tVector(t)],[exp(-h(i)*tVector(t-1)),exp(-h(i)*tVector(t))]);
hold on
end
end
ymax = max();
xlim([1 max(Time)]);
ylim([-0.5 ymax+0.5]);
xlabel('Time')
ylabel('Rate')
end
I think, this is what you want:
function PlotQ(Time,h)
% Parameters
res = 0.1;
n = numel(h);
% Pre-allocate
y = cell(1,n);
t = cell(1,n);
% Calculate
for ii=2:n
t{ii} = Time(ii-1):res:Time(ii);
y{ii} = exp(-h(ii)*t{ii});
end
% Plot
t_ = [t{:}];
y_ = [y{:}];
figure;
plot(t_,y_);
axis([1 max(t_) -0.5 max(y_)+0.5]);
xlabel('Time');
ylabel('Rate');
end
It gives the following plot:

Matlab: Adding third dimenstion to 2D plot

I have the following code to generate me a 2D plot or 2 normal distributions:
res = zeros(2, 320);
index = 1:320;
% assign some data to the res array and then approximate:
PD = fitdist(index','normal', 'frequency', res(1,:)')
pdfNormal = normpdf(index',PD.mu,PD.sigma);
plot(index', pdfNormal, 'Color', 'r', 'LineWidth', 2);
hold on;
PD = fitdist(index','normal', 'frequency', res(2,:)')
pdfNormal = normpdf(index',PD.mu,PD.sigma);
plot(index', pdfNormal, 'Color', 'b', 'LineWidth', 2);
This code generates me then the following picture:
Now I am wondering how I could add a third dimension to this plot? Essentially,
I would like to plot another 2 normal distributions, but this time in the Z-axis,
ie., in the third dimension.
Anyone an idea how I could do that easily?
Thanks so much!
If I understood correctly, you can simply give the plots different z-values. Example:
%# some random data
x = 1:300;
y = zeros(5,300);
for i=1:5
y(i,:) = normpdf(x,100+i*20,10);
end
%# plot
hold on
clr = lines(5);
h = zeros(5,1);
for i=1:5
h(i) = plot(x, y(i,:), 'Color',clr(i,:), 'LineWidth',2);
set(h(i), 'ZData',ones(size(x))*i)
end
zlim([0 6]), box on, grid on
view(3)
hold off