I have two sets of x and y variables. The x variables are not the same or else I would just add the y vectors and plot vs. x, but instead I would like to merge these two vectors by summing them somehow... Any help would be appreciated. Simply plotting them together is not enough, they must be combined.
Simple example:
x1 = [1, 3, 5]
y1 = [1, 2, 3]
x2 = [6, 4, 2]
y2 = [1, 2, 3]
I want to plot y1 + y2 but I have not been able to figure out any ways of doing this yet.
From https://www.mathworks.com/matlabcentral/newsreader/view_thread/37326 :
"Hi,
A problem will arise when the x values of the graphs are not the
same. You than have to interpulate the graphs before the summation.
Here is a small program that will do it:
h=findobj(gca,'type','line'); % assuming there is only one figure exist or %the interesting figure is in focus
for n=1:length(h)
X{n}=get(h(n),'Xdata');
Xmin(n)=min(X{n});
Xmax(n)=max(X{n});
Y{n}=get(h(n),'Ydata');
end
xstart=max(Xmin); xstop=min(Xmax);
x=linspace(xstart,xstop,100); %you can put any other number of points
for n=1:length(h)
y(n,:)=interp1(X{n},Y{n},x);
end
ynew=sum(y,1);
hold on
plot(x,ynew,'k');
You may need to debug the code.
Joe
BSTEX - Equation viewer for Matlab"
Related
Say I have two vectors I want to plot on matlab, and I have this vector that I want to use to mark a small "X" on the plot where this X-value occurs on one of the vectors, how do I do that?
To clarify, say I have a vector of a = [1, 2, 3, 4, 5] another of b = [1, 2, 3, 4, 5, 6] and an identifier vector of a = [1, 4] how do I plot these and show an X on a/b on the plot on x=1 and x =4?
Actually, to find the points that you want, you can use the ismember function as show below.
a=1:5;
c=[1 4];
hold on
plot(a(~ismember(a,c)),'ro') %values of a that DO NOT match the extra entry
plot(a(ismember(a,c)),'rx') %values of a that match the extra entry
I'm not 100% clear if it is this what you want. You can give some comments and I (or someone else) can give you a better answer.
Suppose I have the matrix below:
syms x y z
M = [x+y-z;2*x+3*y+-5*z;-x-y6*z];
I want to have the a matrix consisting the coefficients of the variables x,y, and z:
CM = [1,1,-1;2,3,-5;-1,-1,6];
If I multiply CM by [x;y;z], I expect to get M.
Edit
I have a system of ODE:
(d/dt)A = B
A and B are square matrices. I want to solve these set of equations. I don't want to use ode solving commands of Matlab.
If I turn the above set of equations into:
(d/dt)a = M*a
then I can solve it easily by the eigen vectors and values of matrix M. Here a is a column vector containing the variables, and M is the matrix of coefficient extracted from B.
Since you seem to be using the Symbolic Math Toolbox, you should diff symbolically, saving the derivative with respect to each variable:
syms x y z;
M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
Mdiff=[];
for k=symvar(M)
Mdiff=[Mdiff diff(M,k)];
end
Then you get
Mdiff =
[ 1, 1, -1]
[ 2, 3, -5]
[ -1, -1, 6]
If you want to order the columns in a non-lexicographical way, then you need to use a vector of your own instead of symvar.
Update
Since you mentioned that this approach is slow, it might be faster to use coeffs to treat M as a polynomial of its variables:
syms x y z;
M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
Mdiff2=[];
varnames=symvar(M);
for k=1:length(M)
Mdiff2=[Mdiff2; coeffs(M(k),varnames(end:-1:1))];
end
Note that for some reason (which I don't understand) the output of coeffs is reversed compare to its input variable list, this is why we call it with an explicitly reversed version of symvar(M).
Output:
>> Mdiff2
Mdiff2 =
[ 1, 1, -1]
[ 2, 3, -5]
[ -1, -1, 6]
As #horchler pointed out, this second solution will not work if your symbolic vector has varying number of variables in its components. Since speed only matters if you have to do this operation a lot of times, with many configurations of the parameters in your M, I would suggest constructing M parametrically (so that the coefficients are also syms) is possible, then you only have to perform the first version once. The rest is only substitution into the result.
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 3 arrays X, Y, Z that look something like this:
x = [1, 1, 1, 2, 2, 2, 3, 3, 3]
y = [1, 2, 3, 1, 2, 3, 1, 2, 3]
z = [1, 2, 3, 2, 4, 6, 3, 6, 9]
Then I am plotting these points with plot3(x,y,z).
However the result is something unexpected.. It's basically meant to appear like a log-graph, it does this but it also has extra lines. I have no idea how it's happening, maybe someone here can enlighten me!
Here is an example of my graph (obviously I've plotted my values for X, Y, Z and the arrays above are just an example of what they look like):
As you can see, the bottom curved lines are the log-graph lines which I am happy to be seeing, but the one that appears above it confuse me. I tried displaying the X Y Z values that match the following pattern: X is between 110 and 120 and Y = 0.05. This should theoretically give me TWO matches for each X. ie. Between X = [110, 120], I should get 20 matches since the graph shows two lines hitting at the point Y = 0.05 for each X.
To make it more clear what values of X are being graphed, it's basically increments of 0.1 so between X = 120 and X = 119, it is plotting 119.0, 119.1, ... , 120.0. In any case, only two points of X, Z hit Y = 0.05 between 119-120.
As I was saying, I checked for the values of X, Z that matched Y = 0.05 and it only returns ONE result per X. That is, for X = [110, 120], only 10 matches returned. These values were values on the bottom lines (ie. the log-graph lines) and NOT the top line. So effectively, these lines are not meant to exist. They are definitely hitting Y = 0.05 and are between X = [110, 120] so they should be appearing as a match..
So there you have it. Not really sure what's going on!
If someone could help, that'd be great.
EDIT - More Info.
Even manually putting the X, Y values to the function which returns Z never reaches the values on the upper line.
Thanks.
The example for x, y and z actually illustrates your problem quite well.
You are not plotting individual curves (one for each log-plot) but rather one continuous curve. Hence your extra lines are in fact connecting one end of a log curve to the beginning of the next.
You have to break up your plot command.
Edit
In the end it will require knowledge of your dataset, but for the x, y, z you provided above, this will work to produce three independent curves instead of one:
x = [1, 1, 1, 2, 2, 2, 3, 3, 3];
y = [1, 2, 3, 1, 2, 3, 1, 2, 3];
z = [1, 2, 3, 2, 4, 6, 3, 6, 9];
DATASET_SIZE = 3;
hold on;
for i=1:size(x,2)/DATASET_SIZE
plot3(x((i-1)*DATASET_SIZE+1:i*DATASET_SIZE),y((i-1)*DATASET_SIZE+1:i*DATASET_SIZE),z((i-1)*DATASET_SIZE+1:i*DATASET_SIZE));
plot3(x(i*DATASET_SIZE+1:2*DATASET_SIZE),y(i*DATASET_SIZE+1:2*DATASET_SIZE),z(i*DATASET_SIZE+1:2*DATASET_SIZE));
plot3(x(2*DATASET_SIZE+1:3*DATASET_SIZE),y(2*DATASET_SIZE+1:3*DATASET_SIZE),z(2*DATASET_SIZE+1:3*DATASET_SIZE));
view(3)
end
Edit 2
An easy way of finding out if this "problem" occured, is using the Data Cursor in the MATLAB plot window. Place it anywhere on your graph and use the up or down arrow keys to move around. If you can move along the entire length of the plot, it is a continuous line. Furthermore, you should see the Cursor jump from the "end" of one curve to the "start" of the next.
I had the same problem using surface(x,y,z) and addressed the issue by changing the renderer. MATLAB has 3 different renderers for plotting data and by default the openGL renderer plots as you have shown. You can view hwich renderer your figure uses with GET(gcf). You can change renderer as I have done using: set(gcf,'Renderer','painters')
The 3rd renderer I believe is zbuffer and may work as well.
I am going to draw a graph in Matlab. The graph is quite simple and I am using the plot function.
Suppose the data that I want to plot is (0:1:10). I also put markers on my graph. Then, we have a line that has markers on coordinates (0,0),(1,1),(2,2),... etc.
Now, I want to remove the line between (2,2) and (3,3) without deleting the whole line. That is to say, my purpose is to get rid of a particular segment of the line without loosing the entire line or any marker points.
How can I do that?
Removing the section of line after you have plotted it is difficult. You can see that the line is made up of one MATLAB object by the following code:
x = 1:10;
y = 1:10;
H = plot(x, y, '-o');
get(H, 'children')
ans =
Empty matrix: 0-by-1
We can see that the line has no children, so there are no 'subparts' that we can remove. However, there are some cheeky tricks we can use to try to achieve the same effect.
Plot two lines separately
...using hold on. See Victor Hugo's answer. This is the proper way of achieving our goal.
Plot two separate lines in one
MATLAB doesn'y plot points with a NaN value. By modifying the input vectors, you can make MATLAB skip a point to give the effect of a broken line:
x = [0 1 2 2 3 4 5 6 7 8 9];
y = [0 1 2 nan 3 4 5 6 7 8 9];
plot(x, y, '-o');
This is equivalent to plotting a line from [0, 0] to [2, 2], skipping the next point, then starting again at [3, 3] and continuing to [9, 9].
'Erase' part of the line
This is the nastiest way of doing it, but is a cheap hack that could work if you can't be bothered with changing your input arrays. First plot the line:
x = 1:10; y = 1:10;
plot(x, y, '-o');
Now plot a white line over the part you wish to erase:
hold on
plot([2 3], [2 3], 'w');
As you can see, the result doesn't quite look right, and will respond badly if you try to do other things to the graph. In short, I wouldn't recommend this method but it might come in useful in desperate times!
Try the following:
y = [0.2751 0.2494 0.1480 0.2419 0.2385 0.1295 0.2346 0.1661 0.1111];
x = 1:numel(y);
plot(x(1:4), y(1:4), '-x')
hold
plot(x(5:end), y(5:end), '-x')