I am trying to write a MATLAB script to give me a contour map. The contour map must be created from inputs that I generated from 100 images.
The story is like this:
I have 100 images on which I ran an image processing algorithm for optimization. Now, I got their energy curves. So, I have 100 energy curves. I want to create a contour map that will show me where the points are denser on the plot. (the energy curves are plotted as energy vs. iteration with fixed number of iterations)
The following is my variable:
energy(iteration,numImages)
Hope I explained it well.
Thanks in advance.
I interpret your question to boil down to how can I create a surface plot with colors according to the energy found in energy. I would solve this by using the contour function with a grid generated using meshgrid. If each image is described in 1000 data points with 100 files the plot can be generated as follows:
% using stuff as random junk instead of energy
numPoints = 1000;
numFiles = 100;
stuff = rand(1000,100); % replace with actual information
[X, Y] = meshgrid(1:numFiles, 1:numPoints);
contour(X,Y,stuff);
You can also create a 3D surface plot using surf and the same logic.
From what i see of you graph (and using the comments also), one possible way is to use plot3 to plot a line in 3D for every plot.
For doing so, you can use something like this code:
x=(0:0.01:1)';
aexp=zeros(100,numel(x));
hold on
for ii=1:100;
% aexp(ii,:)=exp((-x+ii/10)); %exponential
aexp(ii,:)=exp(-(x-ii/100).^2); %~gaussian
% aexp(ii,:)= x*ii; %linear increase
plot3(x,aexp(ii,:),ii*ones(1,numel(x)));
end
% set(gca,'yscale','log'); % uncomment if you need logscale.
giving
I have a few options of plot. It always plot from the XY view. I changed by hand, but you can use the view command. Notice that i used a simple counter to make the spacing in the z direction.
In a similar manner, you can plot using the contour. For my code, after the data have been generated in the for loop, remove/comment the plot3 and add:
contour(aexp) %outside the for loop,
giving
Notice that i have not really take care what i'm plotting. You can find more info on contour in the Matlab page .
You commented that the x-axis should be number of iterations, y-axis should be energy and z-axis should be the information containing how many lines are passing through from some areas. For this, make a qq variable, being it qq=number_of_lines(number of iterations,energy) . Make a discrete grid for the energy if you don't have one. Number of iterations is probably discrete anyway. The function is you who need to devise, but i would go for something which checks the number of lines for every energy and every iteration. In this case you will have the z-function that depends on y and x, that is the case to use contour or surface.
My function above make a line for every ii point, to have a 3d function. An edition for another extra loop is not hard. Just remember to have the same regular grid for every point, otherwise you will have trouble.
Related
I have a function f(x,y,t), where for each time point t I have a 2D line plot of x vs. y. I would like to somehow stack all these 2D plots next to each other so that I see the evolution in time t (but not an animation, just a stationary plot). Both x and y variables hold 100 values, and I repeat the calculation t=3500 times. I've organized the output of a function in a 2x100x3500 matrix.
I know that there is a very simple way to make a 3D plot of this matrix, but I have big trouble finding it. Any help is appreciated.
Use waterfall
figure
[X,Y,Z] = peaks(30);
waterfall(X,Y,Z)
In my program, I am doing a least squared optimization problem, i.e. \sum_{i} (y_{i}-y_{i}^{market})^2. At the same time, I want to plot the modeled y_{i} against the y_{i}^{market}. To program it which suit my needs, I define OutputFcn during my optimization and write the code as follow: (Suppose x represent the x-coord
figure()
hold on
plot(x,[y_{1},y_{2},...,y_{n}]);
plot(x,[y_{1}^{market},y_{2}^{market},...,y_{n}^{market}]);
When I run the program, I can draw a new calculated curves on the same plot. Unfortunately, the final plot is difficult to view it. In order to make it to be visible to read, I want to delete the curve (calculated values) obtained in the previous iteration and plot the new curve (calculated values) in the new iteration on the existing plot. What should I do to the current code to fulfill my needs?
Something like:
hold on
for iterations
clf
% PLOT STUFF
drawnow
pause(0.1)
end
clf clears the figure
drawnow forces drawing on screen
pause stops execution for a bit so you have time to see it.
I'm having some difficulty getting a simple script to work. The goal is to rotate an array of points about the origin using some angle. However, the code I'm using seems not to maintain the magnitude of the vector.
Im using a array where the first column is x coordinate and the second is y coordinate:
for ii=1:1000
angleRads=rand()*2*pi;
randRotPoints(ii,1)=1*cos(angleRads)-0*sin(angleRads);
randRotPoints(ii,2)=0*cos(angleRads)+1*sin(angleRads);
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths1=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);
for ii=1:1000
angleRads=rand()*2*pi;
randRotPoints(ii,1)=randRotPoints(ii,1)*cos(angleRads)-randRotPoints(ii,2)*sin(angleRads);
randRotPoints(ii,2)=randRotPoints(ii,2)*cos(angleRads)+randRotPoints(ii,1)*sin(angleRads);
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths2=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);
After the first loop, there is a coordinates of magnitude of 1 and random orientation. This is confirmed via the scatter plot and the lengths1 array is all 1s.
However, the second loop that attempts to rotate those coordinates by a second random angle results in seemingly randomly located coordinates (based on the scatter plot), and the lengths are no longer all 1.
Please help me figure out where I've gone wrong with this rotation code. I know that this isn't the most efficient code in terms of performance or number of lines, if you want to provide a better way to do it in terms of efficiency that is fine, but please also state what would be needed to fix the code in its current format as well.
Thanks.
In your second loop you have
randRotPoints(ii,1)=randRotPoints(ii,1)*cos(angleRads)-randRotPoints(ii,2)*sin(angleRads);
randRotPoints(ii,2)=randRotPoints(ii,2)*cos(angleRads)+randRotPoints(ii,1)*sin(angleRads);
i.e. you use the overwritten (rotated) x coordinate when computing the y. Try saving the randRotPoints(ii,:) vector before rotating it, and using the saved value on the right hand side.
As for making it more efficient:
The more readable solution
You can make the code much more readable by explicitly defining the rotation matrix for each point
for ii=1:1000
angleRads=rand()*2*pi;
rotmat=[cos(angleRads) -sin(angleRads); sin(angleRads) cos(angleRads)];
randRotPoints(ii,:)=rotmat*[1; 0];
%note that this is equivalent to
%randRotPoints(ii,:)=[cos(angleRads); sin(angleRads)];
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths1=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);
for ii=1:1000
angleRads=rand()*2*pi;
rotmat=[cos(angleRads) -sin(angleRads); sin(angleRads) cos(angleRads)];
randRotPoints(ii,:)=rotmat*(randRotPoints(ii,:).');
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths2=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);
In order to spare some code-duplication you could also define a rotmatfun=#(angleRads) [cos(angleRads) -sin(angleRads); sin(angleRads) cos(angleRads); function, then you can just say rotmat=rotmatfun(angleRads); in the loops.
The more efficient solution
You can do away with your loops entirely by making use of the vectorized notation:
N=1000; %number of points
angleRads=rand(N,1)*2*pi;
randRotPoints=[1*cos(angleRads)-0*sin(angleRads), ...
0*cos(angleRads)+1*sin(angleRads)]; %matrix of size [N,2]
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths1=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);
angleRads=rand(N,1)*2*pi;
randRotPoints=[randRotPoints(:,1).*cos(angleRads)-randRotPoints(:,2).*sin(angleRads), ...
randRotPoints(:,2).*cos(angleRads)+randRotPoints(:,1).*sin(angleRads)];
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths2=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);
I am trying to program a matlab code in R2012a that will allow a color representation of temperature change on a surface based on different corresponding height and temperature measurements. Then end goal would be to combine multiple images together to get some sort of a jpeg. The temperatures I recorded were time specific which is why it would be beneficial in the end to have a visual depicting this temperature change over time.
It has been a little bit of time since I have used matlab, and I have never created something This complicated. It has me a little over whelmed and wondering where to start.
Thanks for any and all advice!
You might want to look at the avifile documentation for details on how to create a movie from a series of frames, there is a nice example that should make it clear enough.
Now to generate the frames needed for the avi file. Here, the meshgrid and surf functions come in handy. meshgrid generates two coordinate matrices with x and y coordinates for every point on your plate, surf then allows you to plot a surface with colors given by the temperatures at these positions. For example:
[x,y] = meshgrid(1:5,1:10) % generate a 10*5 plate with step size 1
z = rand(10,5) % height of the plate for a given position
c = rand(10,5) % color values, these should be your (time-dependent) temperatures
surf(x,y,z,c)
It is not clear to me whether you actually have a curved surface (requiring three coordinates to define each position), or just a simple plate. If it is just a simple plate, you can just set z = ones(size(x)) to obtain an uniform height.
I want to assign vector to a contourf graph, in order to show the direction and magnitude of wind.
For this I am using contourf(A) and quiver(x,y), where as A is a matrix 151x401 and x,y are matrices with the same sizes (151x401) with magnitude and direction respectively.
When I am using large maps i get the position of the arrows but they are to densily placed and that makes the graph look bad.
The final graph has the arrows as desired, but they are to many of them and too close, I would like them to be more scarce and distributed with more gap between them, so as to be able to increase their length and at the same time have the components of the contour map visible.
Can anyone help , any pointers would be helpful
i know its been a long time since the question was asked, but i think i found a way to make it work.
I attach the code in case someone encounters the same issues
[nx,ny]= size(A) % A is the matrix used as base
xx=1:1:ny; % set the x-axis to be equal to the y
yy=1:1:nx; % set the y-axis to be equal to the x
contourf(xx,yy,A)
hold on, delta = 8; %delta is the distance between arrows)
quiver(xx(1:delta:end),yy(1:delta:end),B(1:delta:end,1:delta:end),C(1:delta:end,1:delta:end),1) % the 1 at the end is the size of the arrows
set(gca,'fontsize',12);, hold off
A,B,C are the corresponding matrices ones want to use