Ordinary Differential Equations in Matlab - matlab

Question -
I am working on some matlab code that solves 2 first degree differentials and 2 second order differentials. I am ok with dsolve() but when I want to plot I am currently using ezplot and it is not giving me what I want. I want to produce 1 window with four graphs. I know I would use subplot but I dont know how, an example would be nice. Also I dont know how to make my plots show the importiant area not just a large area. my code is below:
close all % close all figure windows that are open
clear all % clear all the variables currently stored in memory
clc % clear the commands in the command window
%%Problem 1%%%%%
a = (dsolve('Dv = -500*v+5000','v(0)=5'));
display (a)
b = (dsolve('Dx = -2000*x+100','x(0)=-.02'));
display (b)
%%Problem 2%%%%%
c = (dsolve('D2y+2000*Dy+26000000*y-520000000=0','Dy(0)=0','y(0)=5'));
display(c)
d = (dsolve('D2y+100*Dy+2500*y-520000000=0','Dy(0)=20','y(0)=0'));
display (d)
figure
ezplot(a);
axis([0,.01,4,10])
figure
ezplot(b);
axis([0,.01,0,10])
figure
ezplot(c);
axis([0,.01,4,10])
figure
ezplot(d);
axis([0,.01,4,10])

I didn't know until now, but it seems that ezplot only generates data points for "interesting part" of your plot. So if you specify the x-limit that ezplot does not use, you don't see anything. What you need to do is to specify the x-limits in its second argument of ezplot. Then, you can create subplots with standard suplot function, get axis handle, and specify the axis. The plotting part of your code should be like this.
figure
h1=subplot(2,2,1);
ezplot(a, [0,0.01]);
axis(h1,[0,0.01,4,10])
h2=subplot(2,2,2);
ezplot(b, [0,0.01]);
axis(h2,[0,.01,0,10])
h3=subplot(2,2,3);
ezplot(c, [0,0.01]);
axis(h3,[0,.01,4,10])
h4=subplot(2,2,4);
ezplot(d, [0,0.01]);
axis(h4,[0,.01,4,10])

Related

Update gramm plot matlab crashing

I have a MATLAB GUI that calls an external function to make a plot (make_ethogram_plot).
The idea would be to have an external figure that is constantly updated with the output value from the figure. Every time the data gets updated it should replot the values, it updates at ~10 Hz. I chose gramm (https://github.com/piermorel/gramm/tree/master/%40gramm) because it is really easy to make a raster plot.
This is the function that gets called. I am having issues to
1) Make it only update in the parent figure with specific name, instead of plotting in the GUI(which is the active figure).
2) Make it not crash. It would open many figures or open or close the same figure at 10 Hz until crashing.
In this configuration, it gives error because it doesn't find g after the first plot. Making g , f, and p1 globals makes it crash (opens every time it gets called)
function make_ethogram_plot(datastructure)
% if the figure doesn't exists create it
if(isempty(findobj(0, 'Name', 'My_gramm_ethogram')))
f=figure('Name', 'My_gramm_ethogram');
p1 = uipanel('Parent',f,'BackgroundColor',[1 1 1],'BorderType','none');
g = gramm('x', datastructure.final_data.frameID, 'color', categorical(datastructure.final_data.behavior));
g.geom_raster();
g.set_parent(p1);
g.draw()
else
% defining f,p1, g here (or having them global) works but crashes
% due to refresh rate
g.update()
end
end
I wrote this code to try to replicate your problem:
function animate_random_data
N = 10000;
data = [cumsum(rand(N,1)),randn(N,1)];
for ii=0:1000
% Plot the data
make_ethogram_plot(data);
drawnow
% Compute new data
data(:,1) = cumsum(rand(N,1));
data(:,2) = randn(N,1);
end
function make_ethogram_plot(data)
fig = findobj(0, 'Name', 'My_gramm_ethogram');
if(isempty(fig))
% If the figure doesn't exists create it
fig = figure('Name', 'My_gramm_ethogram');
ax = axes(fig);
plot(ax,data(:,1),data(:,2));
drawnow
set(ax,'xlimmode','manual','ylimmode','manual');
else
% If it does, update it
line = findobj(fig,'type','line');
set(line,'xdata',data(:,1));
set(line,'ydata',data(:,2));
end
Here, I followed your concept of looking for a named figure window, and creating one if it didn't exist. However, if it does exist, I simply replace the XData and YData property of the line that is already there. This is the fastest way of animating a graph, much faster than deleting the existing plot and creating a new one. After plotting, I use drawnow to update the display. I set XLimMode and YLimMode to manual to prevent re-computation of axes limits and consequent re-drawing of the axes.
The function took 17 seconds to draw all 1000 frames, meaning it's drawing about 60 frames a second. It does not (and should not) crash MATLAB.
You can limit the display rate to 20 frames/sec with drawnow limitrate. It will skip updating the display if the frames come too fast.
I don't know what the gramm/update method does, the class is too complicated to quickly see what is going on, but I dare presume it deletes the axes and creates a new plot from scratch. Not that this should crash MATLAB, it might be worth while to submit a bug report. However, you would probably want to update the figure in the more efficient way, following the method I demonstrated above.
Note that this method can be used to update any of the graphical elements in a plot. For example, I have used this method to animate images.

How to open desired figure by dialogue box in MATLAB

Is there any possible way to open the desired figures from a lot of plotted figures in MATLAB?
If it is possible with dialogue box then it will be perfect.
I have like 75 figures plotted after my code but I have closed the figures at end of loops as they are too much.
Is it possible to open just one figure by just entering values necessary for plotting figure in MATLAB at end of program?
One way to do this is the following:
1) You save the figures as .fig in a dedicated folder using the saveas command, e.g.:
saveas(gcf,['FileName_',num2str(idx),'.fig']);
where idx is the index associated with the figure number (so in 75 in the example you mentioned). For simplicity, I would save all of them in one folder.
2) You use inputdlg to create an input dialog box, where you type in the index you want. Then, you run uiopen(['FileName_',idxFromInput,'.fig']), which will display the figure. Note that the output from inputdlg is normally a string, so you don't need num2str here.
From Wikibooks: MATLAB Programming/Handle Graphics (emphasis mine):
Every time you close a figure, either by using the close function OR by hitting the 'X', you can no longer access the data, and
attempts to do so will result in an error. Closing a figure also
destroys all the handles to the axes and annotations that depended on
it.
This means that once you close your 75 figures, they are gone for good.
I would suggest saving all your figures to .fig file format, because this will allow you to open them later in MATLAB.
Take the following example:
x = linspace(0, 2*pi); % Sample data.
for i = 1:3 % Loop 3 times.
h = figure; % Create figure window and capture its handle.
plot(i*sin(x)); % Plot some data.
saveas(h, sprintf('fig%d.fig', i)); % Save figure to .fig file format.
close(h); % Delete the figure.
end
Now you can tell MATLAB to open one of the figures using the openfig function. For example, let's open the second figure fig2.fig. Go to the Command Window and type openfig('fig2') (including the .fig extension in the file name is optional).
>> openfig('fig2')
ans =
Figure (1) with properties:
Number: 1
Name: ''
Color: [0.9400 0.9400 0.9400]
Position: [520 371 560 420]
Units: 'pixels'
Show all properties

Failed to plot simple graph in Octave

I want to draw a line on a graph to find the intersection point with another line. However, there's no response after I executed the script below. May I know what is the problem and how can I solve it?
x=1:2^20;
y2=2^24;
plot(x,y2);
Thanks!
What you want is to plot a line on 2^24. However, there are too many points for you computer probably, and you run out of memory
I am guessing that you'll need to plot your other inequality as well.
Something like
x=1:100:2^20;
% As Zoran and others suggested, You may not want all the points!
% It is too much memory
y2=2^24*ones(size(x)); % This ones is optional, but its good to know what you are doing (personal opinion)
plot(x,y2);
hold on
y1=(x+1).*log(x);
plot(x,y1);
However, you are still not there!
Another solution, which does not rely on plotting:
>> f = #(x) (x+1)*log(x)-2^24;
>> soln = fzero(f,1e6)
soln = 1.1987e+006
>> f(soln)
ans = 3.7253e-009
So your intersection point is at 1.1987e6.
Apparently,you have too many points for x, 2^20
Have to wait program to calculate, or plot,for example, every 100th point
This solution works for Matlab
x=1:100:2^20;
y2=2^2;
plot(x,y2,'o');
There is one more and maybe a bit smarter way: if you want to solve ((k+1)(ln k)<2^24) as you've commented above, use fsolve function to get just solution of an equation(!). Then use that solution to specify the area of your interest, so you won't have to plot the domain of 2^20.
(All functions are continuous so you don't have to worry about any wild singularities. Just examine the neigborhood of ks for which (k+1)(ln k)-2^24=0.)

matlab printing splitted plot to file

I'm creating a code to do data analysis that will run on a server. The code is supposed to spit a pdf file with 3 plots on it.
I have created a code that generates the plot
fig = figure;
for i = 1:3
%do some calculation to find, X, Y and fit
subplot(3,1,i)
scatter(X,Y)
hold on
plot(X,fit)
end
print (fig, '-dpdf','fig.pdf')
X, Y, and fit are calculated/imported parameters. The output of this code is a pdf document with only the last plot on it (missing the first two).
How can I print all three of them to file?
I tried your code on my CPU (X,Y and fit were generated randomly) and it works fine, so the bug may come from the interaction of this snip of code with you "%do some calculations block"
I would suggest to add a "hold off" command before the end of the for loop ...
gus

problem im motion control with MATLAB

i have a problem in motion control in matlab
imagine a four bar linkage mechanism like this.as you you know in an ordinary 4 bar linkage we have 2 fix points but here we have just one & the second one it fixed to a pinion (small gear).we have the ratio of gears so we have a relation between teta1 & teta2
teta2 = 5*teta1 (the mechanism can rotate in the first fix point)
i used to write this code for motion control but the when i run it the graphs are not correct (because they should be something linke sin or cos graph)
d(n) is a auxiliry vector for solving equations
please ask if you have further questions
this is the code :
clc,
close all,
clear all,
ax=0;
ay=0;
r1=12;
r2=7;
r3=9;
r4=5;
n=0;
for teta1=0:pi/180:2*pi
n=n+1;
D = r1*exp(i*teta1)-r2*exp(i*5*teta1);
tetad(n) = angle(D);
d(n) = abs(D);
landa(n)=acos((d(n)^2+(r3)^2-(r4)^2)/(2*d(n)*r3));
alfa(n)=acos((d(n)^2+(r4)^2-(r3)^2)/(2*d(n)*r4));
teta3(n)=landa(n)+tetad(n);
teta4(n)=(+pi-alfa(n)+tetad(n));
end
aa(n)=teta1*180/pi;
hh(n)=tetad(n)*180/pi;
bb(n)=landa(n)*180/pi;
cc(n)=alfa(n)*180/pi;
nn(n)=teta3(n)*180/pi;
dd(n)=5*teta1*180/pi;
ee(n)=teta4(n)*180/pi;
figure(1),plot(aa,hh),xlabel('teta1'),ylabel('tetad');
figure(2),plot(aa,d),xlabel('teta1'),ylabel('d');
figure(3),plot(aa,bb),xlabel('teta1'),ylabel('landa');
figure(4),plot(aa,cc),xlabel('teta1'),ylabel('alfa');
figure(5),plot(aa,nn),xlabel('teta1'),ylabel('teta3');
figure(6),plot(aa,dd),xlabel('teta1'),ylabel('5*teta1');
figure(7),plot(aa,ee),xlabel('teta1'),ylabel('teta4');
I have no idea what you are trying to solve here, but probably you want to move the end of your for-loop a few lines down, so the vectors you plot contain all values and not only the last one.