Change Matlab default x-limits behavior - matlab

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.

Related

Matlab skipping plots (uncertainty)

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)

Set figure to not be target for next plot

I'm working on a custom progress monitor with some graphs. I've noticed that Matlab's waitbar creates a figure with some special properties so that if you do
plot(rand(100,1));
wb = waitbar(0);
plot(rand(100,1));
the second plot ends up replacing the first plot and not in wb. Is there a property I can set so that when I create my progress monitor and then plot something afterwards, the graph doesn't end up in my figure?
To be clear, I'm trying to have
plot(rand(100,1));
temp = MyProgressBar();
plot(rand(100,1));
create a figure for the first plot, create a different figure in the second line, then plot a new graph in the third line.
To protect your progress bar figure against subsequent plotting operations, I would set the 'HandleVisibility' property of its axes to 'off'. That should prevent it ever becoming the current axes, thus keeping subsequent plotting commands from modifying or adding to it. It's a good practice for stand-alone figures/GUIs in general that you turn off the handle visibility of all objects (figure, uicontrols, etc.) in this way to insulate them against being modified by outside code. This is almost certainly what is done in the code for waitbar.
As an additional aside, it's good practice to target your plots to a given axes by passing the axes handle as the first argument. You also have to make sure that, if you want new plots to be added to existing plots, you use things like the hold command first. Here's how I'd rework your example, assuming you want the two plots to appear on the same axes:
plot(rand(100,1)); % Creates new figure and axes
hAxes = gca; % Get the axes handle
hold on; % Allow subsequent plots to be added
temp = MyProgressBar();
plot(hAxes, rand(100,1)); % Will be added to the first plot axes

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.

how to set axis limits in matlab globally?

It seems trivial but I couldn't find a way to do it. I have plot in a function and I'm passing data from the main function. In the main function, I set the axes like this axis([-10, 10, -10, 10]);; however, every time I call the function which has plot, it changes the axes automatically. Is there a way to set the figure globally so that all functions can use one figure with fixed properties?
You can setup x and y axis limits globally as follows (at least in R2013a):
set(0,'defaultaxesxlim',[-10 10]);
set(0,'defaultaxesylim',[-10 10]);

MATLAB: Plotting two different axes on one figure

The MATLAB surf plot below is essentially two plots plotted adjacent to each other. For clarity, I have included some code below used to prepare the plot:
band1 = horzcat(band1, eSurface2(:,:,1));
band2 = horzcat(band2, eSurface2(:,:,2));
surf(band2,'DisplayName','band2');
surf(band3,'DisplayName','band2');
I would like for the y axis numbering to restart at the start of the second graph. How do I go about doing that?
You can use the 'YTick' and 'YTickLabel' properties of the axis to control the ticks, this way you can make it start from zero for the second graph. It will require some trail and error to get it right. See the relevant doc here (you'll have to scroll all the way to the bottom of the page).
Take advantage of the following feature of 'YTickLabel': "If you do not specify enough text labels for all the tick marks, MATLAB uses all of the labels specified, then reuses the specified labels".