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.
Related
I have a function in MATLAB and it plots two curves and I run it two times.
On the first time plot main curve as you can see in the red color (first plot) and after that turn the "hold on" and execute my function again with the green color (second shape).
The problem is that the left subplot does not work and delete the first curve (red curve) but the second one works fine (last plot).
My main script is:
% some code to processing
...
roc('r.-',data); %this function plots my curves
and on the second run
% some code to processing
...
plot on
roc('g.-',data);
and my roc function contains:
%some code
...
subplot(1,2,1)
hold on
HCO1=plot(xroc(J),yroc(J),'bo');
hold off
legend([HR1,HRC1,HCO1],'ROC curve','Random classifier','Cut-off
point','Location','NorthOutside')
subplot(1,2,2)
hold on
HCO2=plot(1-xroc(J),yroc(J),'bo');
hold off
legend([HR2,HRC2,HCO2],'ROC curve','Random classifier','Cut-off
point','Location','NorthOutside')
disp(' ')
%....
Assuming your roc function calculates xroc and yroc I suggest you rewrite your code to modularize it
function [xroc,yroc] = roc(data)
%your algorithm or training code
%xroc=...
%yroc=...
end
this way your main script could be edited to something like this
%first run
[xroc1,yroc1] = roc(data);
%...some further processing with data variable
[xroc2,yroc2] = roc(data);
%plots
ax1 = subplot(1,2,1,'nextplot','add'); %create left axes
ax2 = subplot(1,2,2,'nextplot','add'); %create right axes (mirrored roc)
%now you can go ahead and make your plots
%first the not mirrored plots
plot(xroc1,yroc1,'r','parent',ax1);
plot(xroc2,yroc2,'g','parent',ax1);
%and then the mirrored plots
plot(1-xroc1,yroc1,'r','parent',ax2);
plot(1-xroc2,yroc2,'g','parent',ax2);
it is a little effort to rewrite but it surely will help to make your code scaleable to if you want to add more than just two curves in future.
Quite a simple question but just couldn't find the answer online... I want to visualise a point cloud gathered from a lidar. I can plot the individual frames but wanted to loop them to create a "animation". I know how to do it for normal plots with drawnow but can't get it working with a scatter3. If I simply call scatter3 again like I have done in the commented code then the frame that I am viewing in the scatter plot jumps around with every update (Very uncomfortable). How do i get the scatter3 plot to update to the new points without changing the UI of the scatter ie. Still be able to pan and zoom around the visualised point cloud while it loops through.
EDIT: The file is a rosbag file, I cannot attach it because it is 170MB. The problem doesn't happen when using scatter3 in a loop with a normal array seems to be something with using scatter3 to call a PointCloud2 type file using frame = readMessages(rawBag, i).
EDIT: The problem does not seem to be with the axis limits but rather with the view of the axis within the figure window. When the scatter is initialised it is viewed with the positive x to the right side, positive y out of the screen and positive z upwards, as shown in view 1. Then after a short while it jumps to the second view, where the axis have changed, positive x is now out of the screen, positive y to the right and positive z upwards (both views shown in figures). This makes it not possible to view in a loop as it is constantly switching. So basically how to update the plot without calling scatter3(pointCloudData)?
rawBag = rosbag('jackwalking.bag');
frame = readMessages(rawBag, 1);
scatter3(frame{1});
hold on
for i = 1:length(readMessages(rawBag))
disp(i)
frame = readMessages(rawBag, i);
% UPDATE the 3D Scatter %
% drawnow does not work?
% Currently using:
scatter3(frame{1})
pause(.01)
end
The trick is to not use functions such as scatter or plot in an animation, but instead modify the data in the plot that is already there. These functions always reset axes properties, which is why you see the view reset. When modifying the existing plot, the axes are not affected.
The function scatter3 (as do all plotting functions) returns a handle to the graphics object that renders the plot. In the case of scatter3, this handle has three properties of interest here: XData, YData, and ZData. You can update these properties to change the location of the points:
N = 100;
data = randn(N,3) * 40;
h = scatter3(data(:,1),data(:,2),data(:,3));
for ii = 1:500
data = data + randn(N,3);
set(h,'XData',data(:,1),'YData',data(:,2),'ZData',data(:,3));
drawnow
pause(1/5)
end
The new data can be totally different too, it doesn't even need to contain the same number of points.
But when modifying these three properties, you will see the XLim, YLim and ZLim properties of the axes change. That is, the axes will rescale to accommodate all the data. If you need to prevent this, set the axes' XLimMode, YLimMode and ZLimMode to 'manual':
set(gca,'XLimMode','manual','YLimMode','manual','ZLimMode','manual')
When manually setting the limits, the limit mode is always set to manual.
As far as I understood what you describe as "plots jumpying around", the reason for this are the automatically adjusted x,y,z limits of the scatter3 plot. You can change the XLimMode, YLimMode, ZLimMode behaviour to manual to force the axis to stay fixed. You have to provide initial axes limits, though.
% Mock data, since you haven't provided a data sample
x = randn(200,50);
y = randn(200,50);
z = randn(200,50);
% Plot first frame before loop
HS = scatter3(x(:,1), y(:,1), z(:,1));
hold on
% Provide initial axes limits (adjust to your data)
xlim([-5,5])
ylim([-5,5])
zlim([-5,5])
% Set 'LimModes' to 'manual' to prevent auto resaling of the plot
set(gca, 'XLimMode', 'manual', 'YLimMode', 'manual', 'ZLimMode', 'manual')
for i=2:len(x,2)
scatter3(x(:,i), y(:,i), z(:,i))
pause(1)
end
This yields an "animation" of plots, where you can pan and zoom into the data while continuous points are added in the loop
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.
I am trying to plot a figure that changes with time (think of it as plotting the shape of a pole as the wind passes through it, so I want to plot the shape at every second).
To avoid the x axis limit changing frequently I want to fix it to the limits (max and min that I calculate before plotting). Here is a sample of my code:
for i=1:1:numberofrows
momentvaluesatinstant = momentvalues(i,:);
figure(1)
plot(momentvaluesatinstant,momentheader)
drawnow
title(sprintf('Moment profile along pile at time 0.2%f',time(i)'))
xlabel('Moment (kN.m)')
xlim([momentvalues(rowminmoment) momentvalues(rowmaxmoment)])
ylabel('Length of pile (m)')
delay(1);
end
Although I am specifying the limits of the x axis to be fixed to the values I specify, the plot keeps changing the limits depending on the data being plotted? Is there something I am missing?
Figured it, need to add xlim manual
I'm not sure why you needed xlim manual, but here is a more compact and correct way to animate your data:
% use 'figure', `plot` and all the constant parts of the figure only once, before the loop.
figure(1)
m = plot(momentvalues(1,:),momentheader); % plotting only step 1
xlim([momentvalues(rowminmoment) momentvalues(rowmaxmoment)])
xlabel('Moment (kN.m)')
ylabel('Length of pile (m)')
% loop from step 2 ahead
for k = 2:length(momentvalues)
pause(1); % use pause to set the delay between shots
% use 'set' to change the x values
set(m,'Xdata',momentvalues(k,:));
drawnow
title(sprintf('Moment profile along pile at time 0.2%f',k))
end
I can use the subplot to display multiple images in the same window. for example, I have two images displayed by:
figure,
subFig1=subplot(1,2,1)
surface(rawx,rawy,rawz) % 3D object
subFig2=subplot(1,2,2)
plot(x,z) %profile of the surface.
Assuming rawx, rawy,rawz is the orginal data and x,y,z is measured data. I am using the iteration 'for' to read the measured data.
During the loop, is it possible to hold subFig1 and plot measured profile on top of the surface, and in the mean time, subFig2 can still display the profile in 2D and refresh when the new measurements coming.
I guess this can be done by different handle. However, I can't find any cue so far. please help.
Axes in a subplot behave the same way than in figures. The last subplot called is still active.
In your case, the solution would be:
figure,
subFig1=subplot(1,2,1)
surface(rawx,rawy,rawz)
subFig2=subplot(1,2,2)
hold on
plot(x,z)
for ...
x= ... % your new value
z= ...
plot(x,z) % subplot 122 still active and still hold
end