Matlab skipping plots (uncertainty) - matlab

I have a sequence of finding fits for data (cd to folder, read and fit the data) and subsequently plotting them in a loop.
I observe that few plots are done incorrectly, skipped and added in subsequent plots. A four second pause between each plots seems to solve this issue.
I assume everything is sequential in Matlab, meaning subsequent commands wait until current command is finished. I believe this is not the way happening now. I believe using pause is not the best solution. Can someone provide a fix for this?
A set of subsequent plots without the pause (solid line is a fit of datapoints on the fly):
The same plots with pause of 4 seconds:

subplot, and most other functions that generate graphics objects, provide a handle to the generated graphics object that you can use to address the object explicitly with functions like plot.
If an explicit axis handle is not provided to a plotting function, it will use the current axes, which can very often lead to issues like these. So much so that it's caveated in the documentation:
User interaction can change the current axes or chart. It is better to assign the axes or chart to a variable when you create it instead of relying on gca.
So rather than doing:
axes
plot(1:10)
You should do the following:
ax = axes;
plot(ax, 1:10)

Related

Change Matlab default x-limits behavior

If I run
plot(1:1001)
Matlab automatically sets the x range to be 1:1200. I am aware that xlim([1,1001]) exists, but I don't want to add this line every single time I use plot.
Is there a way to change Matlab's behavior so that plot sets the x-limits equal to the range of the data by default instead of having to do it manually every time? (For example with a flag I can set at the top of my script).
Or a parameter I can pass to plot to make this happen?
You could set your default XlimSpec property for Axes.
set(0,'defaultAxesXLimSpec', 'tight')
Then when you plot it will use X axes tight setting for every new plot.
This will revert back to normal after you close & restart Matlab. However, you could add that to your startup script to always apply it.
This meets some of your requirements I saw you mentioned in the comments about not using a wrapper and trying to minimize running extra commands after call plot
Matlab uses an internal algorithm to determine the best interval of axis ticks. I doubt you can manipulate it and, even if it was possible, I recommend you not to do it. Such operation would change the behavior of your own Matlab installation, but everybody else using your code would stumble upon a different axis labelling probably not well fitting with your purposes.
Keep on defining your ticks manually or implement your own generalized logics into a separate function that you can release together with your scripts. This code shows how to implement one, and can represent a good starting point for you.
If you want to make things simpler, create a wrapper of the plot function as follows:
h = plot_wrapper(true,1:101,1:101);
function varargout = plot_wrapper(fix_limits,varargin)
han = plot(varargin{:});
if (fix_limits)
x = get(han,'XData');
xlim(gca,[min(x) max(x)]);
y = get(han,'YData');
ylim(gca,[min(y) max(y)]);
end
if (nargout)
varargout{1} = han;
end
end
You want the x-axis limits to tightly fit your data. If you don't mind the y-axis also having that behaviour, you can simply use
plot(1:1001)
axis tight
From the documentation,
axis tight sets the axis limits to the range of the data
If you want only the x-axis to be tight, you can do it manually as follows:
h = plot(1:1001); % h is a line object
h.Parent.XLim = [min(h.XData) max(h.XData)]; % set x-axis limits as per the line data
Note that the second line uses dot notation, which is available since R2014b. For older Matlab versions use set/get .
Or you can do it automatically by setting the seemingly undocumented 'XLimSpec' property of the axis to 'tight':
plot(1:1001)
set(gca, 'XLimSpec', 'tight')
which is what axis tight internally does (for the x-, y- and z-axis), at least in R2017a.

Linking plotted data with color and size sources in MATLAB

This question is related to the question posted here, in which I outline a problem I'm facing regarding rapid visualization of 3D scatter plotted data in MATLAB during a simulation. (Sample code and data are also provided there.)
As an alternative to setting the XData, YData, ZData, SizeData, and CData properties of a 3D scatter plot in MATLAB, I'm wondering if it's possible to have all of their corresponding sources be dynamically linked to points that are 3D scatter plotted. The linked values would be queued into a buffer and plotted periodically (say, every 0.5 s). From what I understand, the sources are refreshed in the background, so plots with linked data would not slow down the simulation. From what I see in the documentation, only XDataSource, YDataSource, and ZDataSource are specified. Is dynamically linking the size and color data sources also possible, and if not, is there a simple workaround?
As a reminder, I'm using MATLAB R2016a on Windows 7.
Is dynamically linking the size and color data sources also possible, and if not, is there a simple workaround?
Yes, it is possible using the similarly named properties
SizeDataSource
CDataSource
These properties are set to the string names of the variables you want linked for updating. Then, with linking on, subsequent updates to these named variables will be reflected in your plots ever 1/2 second or so (at the fastest).
But, there is a big caveat here with your specific example.
The xxxxSource fields are typically initialized at the outset, when a graphic handle is created. This would be in your initial scatter3 calls.
The issue is that you have eight separate scatter plot handles, each referencing the same variable(s), but with different indexes. That is, you are updating the indices into these variables to produce your images.
A brute force way to use parameter linking here would be to create eight different variable names and link each to its corresponding scatter plot handle.
I think the cleaner solution is to use a timer callback to update things on a set time interval.

Drawnow on Matlab: It store the figure or store the variable?

May you please help me on a question on DRAWNOW in Matlab?
When we using drawnow in Matlab, what happens inside?
It stores the figure of the previous-graph, then plot the next-part-of-graph on the same figure?
OR it forgets the whole previous-graph and plot the actual-new-graph (with both previous and next-part)?
The both methods show the same effect: a dynamic graph. But I want to know exactly what happens inside.
Thank you!
drawnow makes sure that MATLAB stops doing whatever its doing and draws in the screen.
If you do
hold on
for ii=1:1000
plot(ii,rand(1)); % assume complicated maths here
end
MATLAB will run the code and send the plot calls to the graphics engine. However, MATLAB is too busy running the loop to be drawing, as the code has priority over the plot.
If you do
hold on
for ii=1:1000
plot(ii,rand(1));
drawnow; % Take a break, draw everything that you must before continuing
end
Then, as the comment says, you temporarily stop the execution of the code, to draw everything in the graphics pipeline, and then continue executing the code.
drawnow has no influence in the fact that the figure is stored or not, that is the job of hold on.
If you are worried about redrawing the whole thing, then make sure you have a look at set and get methods for graphics. With them you can get the xdata, modify it, and set it again, by ensuring that the graphics engine does not redraw/recompute anything else.
Documentation for the hold function:
https://uk.mathworks.com/help/matlab/ref/hold.html

Unable to plot multiple data sets in GUIDE

I'm using GUIDE to display a plot within an axis that contains two data sets: the original signal and the average of the signal, but for some reason it seems to only plot one.
The axis is designated as m_graph and the data sets are avg and signal, which both share time.
plot(handles.m_graph, time,signal)
hold on
plot(handles.m_graph, time, avg)
When I compile the program, only the average is plotted. It seems to skip over the original signal or reset the axis. I've tried plotting just the signal so I know the data is fine.
I feel like I am missing something, maybe the set function?
Sorry my reasoning was a bit wrong; it applies to the current selected axes (it does not parent to the Figure).
However, using axes(h) followed by hold on or just hold(h,'on') will either switch the focus to the axes then turn hold on or turn hold on for a specified axes, respectively.

Why won't this axes object display correctly in MATLAB?

I am writing two small psychoacoustic testing applications in MATLAB. The first one works without problems but the second one doesn't, and I just can't figure out why.
Here is the problem: the axes object is created, but it is empty.
failed_axis http://dl.getdropbox.com/u/98854/help.png
Here is the code that creates this figure and axes:
hFig = figure('dockcontrols','off','menubar','none', ...
'name','choose the better sounding file', ...
'numbertitle','off','position',[0,0,700,500], ...
'resize','off','toolbar','none','units','normalized', ...
'color',[.8,.8,.8]);
progress_idc = axes('position',[.1,.8,.8,.05],'box','on','parent',hFig,...
'xlim',[-.03,1.03],'xtickmode','manual','xtick',[], ...
'xticklabelmode','manual','xticklabel',[], ...
'ylim',[-1,1],'ytickmode','manual','ytick',[], ...
'yticklabelmode','manual','yticklabel',[], ...
'nextplot','add');
And here is the code that plots in this axes (the function is called regularly by a timer):
function replot(varargin) % this is a nested function
cla;
% plot start_indicator
plot([x_start,x_start],[-.7,.7],'k','linewidth',2);
fill([x_start,x_start-.02,x_start-.02],[0,-.7,.7],[0,0,0]);
% plot stop_indicator
plot([x_stop,x_stop],[-.7,.7],'k','linewidth',2);
fill([x_stop,x_stop+.02,x_stop+.02],[0,-.7,.7],[0,0,0]);
% plot play_position
plot([x_play,x_play],[-1,1],'r');
drawnow;
end
This is what it looks like if it works:
proper_axis http://dl.getdropbox.com/u/98854/help2.png
Do you have any idea what is going wrong here?
I ran the code you included above and got the correct output.
If I had to take a wild guess as to what the problem is, I'd guess that you may be creating other axes in your application that you are not listing above, or that you may have other axes not related to the application open at the time the application is running. When you plot your objects in the function replot, you are by default plotting them to the currently active axes. If you have multiple axes open, the plotting may therefore be going on in the wrong set of axes.
One suggestion I would make is to explicitly specify what the parent axes object should be in your calls to PLOT and FILL. If you add the arguments ...,'Parent',progress_idc); to your plotting calls, it will ensure that the correct axes is always used. I make a habit of always specifying the parent axes object instead of assuming that the currently active axes will always be the one I need it to be.
I finally found the (dumb) answer. The title accidentally had the same position as the plot axis. Due to some rendering-details of Matlab, it obscures the whole axis except for the rightmost and bottommost line of pixels, which makes the axis look "empty".
Oh, what a dumb error.