I have a matlab indexing question. I have a vector of 34 elements that I would like to plot in a for loop. However, I do not wish to plot them all at once. It would be great if I were able to plot elements 1:6, then 7:11, then 12:20, and so on. Is it possible to do this type of plotting in a for loop? If it is, I am having trouble with the indexing. Since these elements are all in sequential order, matlab seems to want to plot them all together. Any help would be appreciated. Thanks!
Here is an example of what I am trying to do:
for i = 1: [1:6, 7:11, 12:20]
plot(x(i), y(i))
end
Hopefully, I can get three plot, one with data from elements 1:6, another from elements 7:11, and the last one from elements 12:20.
You can just use a cell to store the variable-length vectors containing the various indices:
x = linspace(0, 1, 20);
y = x;
i_cell = {1:6, 7:11, 12:20};
for i = 1:length(i_cell)
figure
indices = i_cell{i}
plot(x(indices), y(indices))
end
Related
I have a matrix, 10x10x40, that is storing information of an image through time, where the the rows and columns indicate the spectral value at a specific point, and the third dimension is time. So in other words, a 10x10 image at 40 points in time. I would like to loop through each row, column and view that pixel history (1,1,:), (1,2,:)....(10,10,:).
Here's what I'm doing now:
val = [];
for i = 1:10;
for j = 1:10;
for k = 1:length(timevector)
val(k) = my_matrix(i,j,k);
end
end
end
Since I want to iterate through each pixel in time and then save that data, what would be the best way to store the new value/time vectors? I want to end up with 100 pixel history vectors, right now I end with one, and it's because val is written over within the loop. I know it's not advised to create variables within a loop, so what is the best alternative? Should I look into storing the output as a structure? I've been staring at this and I have over-complicated everything.
Depending on the structure you prefer, you can also use matlab's functions reshape and num2cell to get the output in the following form:
Alternative 1:
A = reshape(A,[],10);
This will return a matrix (100x40) where each row is a pixel's history.
Alternative 2:
A = num2cell( reshape(A,[],40), 2)
This will return a cell array (100x1) where each cell contains a vector (40x1) with each pixel's history.
Alternative 3:
A = squeeze( num2cell( permute(A, [3,1,2]), 1) );
This will return a cell array (10x10) where each cell contains a vector (40x1) with each pixel's history.
Depending on what you want to do with it, you don't need to store them in separate vectors. You can just get one of these pixel history vectors, like so,
pixel_history = squeeze(my_matrix(1,1,:));
squeeze will remove the singleton dimension from the slice, and make it into a 40-by-1 vector, instead of a 1-by-1-by-40 matrix.
To make the time dimension the first matrix dimension, you could also permute the matrix,
permute(my_matrix, [3 2 1]);
This will swap the 3rd and 1st dimensions, making the 1st dimension time.
I am using ode45 to solve a system with 4 variables. For each time I execute the code:
[t y] = ode45(#func, tspan, y0);
t will be a one dimensional matrix, while y will be a 2 dimensional matrix, with 4 columns, each of which is the solution for one of the variables in question.
I want to run multiple trials of this, and keep them in a 3D matrix my_y_results and my_t_results. I want to be able to, for example, plot the final value of a certain variable for a particular initial condition, as I change the initial condition. How would I do this?
So, on each iteration of the loop below, I want to place the new values in a new matrix.
for i = 1:1:10
y0 = **some value**
[t_temp, y_temp] = ode45(#func, tspan, y0);
my_t_results = **something**
my_y_results = *something* //your code here
end
Also, how would I access the different values after setting them? For example, to get the last value of the variable y(1) for each of the 10 trials, what code would I use?
Higher dimensions can be accessed similar to the usual row and column dimensions. Let's assume t is Nx1 and y is Nx4, and that we are running M trials (note that each trial will have to have the same number of points, N, in order to store the data in a 3-dimensional array).
Your array my_t_results doesn't have to be 3-dimensional and can simply be NxM, where each column is the time vector for a different trial.
The array my_y_results would be Nx4xM and can be defined in MATLAB with:
my_y_results = zeros(N,4,M);
At the end of each i'th trial you would store the results like this:
my_y_results(:,:,i) = y;
And of course accessing the data is similar:
y_i = my_y_results(:,:,i);
This is a continuation of my previous problem, so now i want to know how to change array size and how to use size(out) = [m n].
so basically if you have 10x10 array and you want to plot column 9 vs. column 10 in scatter plot, and you want column 1-column 8 to be the labels of your scatter plot. how can i use size(out) = [10 10]?
for someone who want examples:
Auto-Label in scatter plot using matlab
and what if your array is m x n? is there a general code for this? please enlighten me, thanks.
To make things more general you can make use of the end keyword, which refers to the last row/column or an array/cell array/anything in Matlab (actually "last array of index").
Revisiting your example, you could use num2str (alternatively to sprintf) and use the following:
scatter(out(:,end-1), out(:,end));
for k = 1:size(out,1)
T{k} = num2str(out(k,1:end-2));
end
xshift = 0.03; yshift = 0.03;
text(out(:,3)+xshift, out(:,4)+yshift, T);
grid on
Which gives this:
I have got a cell, which is like this : Data={[2,3],[5,6],[1,4],[6,7]...}
The number in every square brackets represent x and y of a point respectively. There will be a new coordinate into the cell in every loop of my algorithm.
I want to plot these points into a time-changing curve, which will tell me the trajectory of the point.
As a beginner of MATLAB, I have no idea of this stage. Thanks for your help.
Here is some sample code to get you started. It uses some basic Matlab functionalities that you will hopefully find useful as you continue using it. I added come data points to you cell array for illustrative purposes.
The syntax to access elements into the cell array might seem weird but is important. Look here for details about cell array indexing.
In order to give nice colors to the points, I generated an array based on the jet colormap built-in in Matlab. Basically issuing the command
Colors = jet(N)
create a N x 3 matrix in which every row is a 3-element color ranging from blue to red. That way you can see which points were detected before other (i.e. blue before red). Of course you can change that to anything you want (look here if you're interested).
So here is the code. If something is unclear please ask for clarifications.
clear
clc
%// Get data
Data = {[2,3],[5,6],[1,4],[6,7],[8,1],[5,2],[7,7]};
%// Set up a matrix to color the points. Here I used a jet colormap
%// available from MATLAB but that could be anything.
Colors = jet(numel(Data));
figure;
%// Use "hold all" to prevent the content of the figure to be overwritten
%// at every iterations.
hold all
for k = 1:numel(Data)
%// Note the syntax used to access the content of the cell array.
scatter(Data{k}(1),Data{k}(2),60,Colors(k,:),'filled');
%// Trace a line to link consecutive points
if k > 1
line([Data{k-1}(1) Data{k}(1)],[Data{k-1}(2) Data{k}(2)],'LineStyle','--','Color','k');
end
end
%// Set up axis limits
axis([0 10 0 11])
%// Add labels to axis and add a title.
xlabel('X coordinates','FontSize',16)
ylabel('Y coordinates','FontSize',16)
title('This is a very boring title','FontSize',18)
Which outputs the following:
This would be easier to achieve if all of your data was stored in a n by 2 (or 2 by n) matrix. In this case, each row would be a new entry. For example:
Data=[2,3;
5,6;
1,4;
6,7];
plot(Data(:, 1), Data(:, 2))
Would plot your points. Fortunately, Matlab is able to handle matrices which grow on every iteration, though it is not recommended.
If you really wanted to work with cells, there are a couple of ways you could do it. Firstly, you could assign the elements to a matrix and repeat the above method:
NumPoints = numel(Data);
DataMat = zeros(NumPoints, 2);
for I = 1:NumPoints % Data is a cell here
DataMat(I, :) = cell2mat(Data(I));
end
You could alternatively plot the elements straight from the cell, though this would limit your plot options.
NumPoints = numel(Data);
hold on
for I = 1:NumPoints
point = cell2mat(Data(I));
plot(point(1), point(2))
end
hold off
With regards to your time changing curve, if you find that Matlab starts to slow down after it stores lots of points, it is possible to limit your viewing window in time with clever indexing. For example:
index = 1;
SamplingRate = 10; % How many times per second are we taking a sample (Hertz)?
WindowTime = 10; % How far into the past do we want to store points (seconds)?
NumPoints = SamplingRate * WindowTime
Data = zeros(NumPoints, 2);
while running
% Your code goes here
Data(index, :) = NewData;
index = index + 1;
index = mod(index-1, NumPoints)+1;
plot(Data(:, 1), Data(:, 2))
drawnow
end
Will store your data in a Matrix of fixed size, meaning Matlab won't slow down.
So I'm still getting used to Matlab and am having a bit of trouble with plotting. I have a cell which contains a list of points in each row. I want to plot each row of points in a different colour on the same graph so I can compare them. The catch is that I need to make this work for an unknown number of points and rows (ie the number of points and rows can change each time I run the program).
So for example, I might have my cell array A:
A = {[0,0], [1,2], [3,4]; [0,0] [5,6], [9,2]}
and I want to plot the points in row 1 against their index (so a 3D graph) and then have the points in row 2 on the same graph in a different colour. The rows will always be the same length. (Each row will always have the same number of points). I've tried a few different for loops but just can't seem to get this right.
Any help in sending me in the right direction would be greatly appreciated!
The fact that the number of points and rows can change with each iteration should not pose much of a problem. I would suggest using the size function before your plot loops (size(A,1) and size(A,2)) to get the dimensions of the matrix.
Once you have the size of the matrix, loop through the dimensions and plot the lines on the same plot using holdon, and then finally just make the line color a function of the dimensions as you loop through so that you always have a different line color
You could just convert it to a matrix and plot it directly:
% Some dummy data - format a little different from your example
% to allow for different numbers of elements per row
A = {[0,0, 1,2, 3,4]; [0,0, 5,6]};
% Figure out how many columns we need in total
maxLen = max(cellfun(#length, A));
% Preallocate
Amat = NaN(size(A, 1), maxLen);
% Copy data
for n = 1:size(A, 1)
curA = A{n};
Amat(n, 1:length(curA)) = curA;
end
% Generate 1:N vector repeated the correct number of times (rows)
x = repmat(1:size(Amat, 2), size(Amat, 1), 1);
plot(x, Amat)
Edit: You mentioned a 3D graph at some point in your post. The above won't plot a 3D graph, so here's something that will:
% Generate Amat as above
% Then:
[X, Y] = meshgrid(1:size(Amat, 1), 1:size(Amat, 2));
surf(X, Y, Amat.'); % OR: plot3(X, Y, Amat.');
I'm not sure this is exactly what you want, but your question is slightly unclear on exactly what kind of graph you want out of this. If you just want coloured lines on your plot, you can use plot3 instead of surf, but IMHO surf will probably give you a clearer plot for this kind of data.