I like to plot things when I'm testing, but for the full run I would like the plotting to be turned off in an easy and efficient way. Currently I have a variable at the top of the script as follows
plotting = true;
Then, in all the sections with plotting, I have something along the lines of
if plotting
figure;
plot(x,y)
...
end
So of course if I don't want to plot, I simply set plotting = false;
at the top of the script.
Is there a better, more efficient way of doing this? Or does anyone have a method that they use that is different?
As mentioned in the comments, your current method is about as good as it gets... Here is a note on that method and an alternative though.
Keeping the editor warnings tidy
The MATLAB editor will underline the first line in your if statement if you use the syntax you've show, i.e. no comparison operator on a Boolean:
plotting = false;
if plotting
figure % <- this line will be underlined orange
% as the editor "knows" it will never be reached!
% ...
end
A quick fix is to use an equals comparison (==) which the editor doesn't check in the same way. This is also more explicit and slightly clearer for future reference:
plotting = false;
if plotting == true
figure % <- this line is now not highlighted
% ...
end
Using figure-number arrays
You use the word "efficient" in your question. You won't find a more efficient method than the two-liner above, but you might want to play around with arrays of figures. This method allows you to specify certain figures for plotting, and means you can have an array of optional figures:
plotting = [1 3]; % We want to plot figures 1 and 3
if any(plotting == 1)
figure(1); % do stuff with figure 1
end
if any(plotting == 2)
figure(2); % won't enter this condition because plotting = [1 3]
end
if any(plotting == 3)
figure(3); % do stuff with figure 3
end
If you don't want to plot anything, simply set plotting = [];
Note that if you had many similar figures then the 3 above conditionals could be placed in a simple loop, with minor variations (dictated by further if statements) in each plot.
You can add the line:
set(0,'DefaultFigureVisible','off')
At the beginning of your code to keep figures hidden.
Undo this by setting:
set(0,'DefaultFigureVisible','on')
Note that the figures and plots are still created, just hidden.
Example:
set(0,'DefaultFigureVisible','off') % Visible off
figure(6); % This figure will be created but hidden
plot(6:8); % Plot is created but on the hidden figure
set(0,'DefaultFigureVisible','on') % Visible on
figure(6); % The figure will now be shown, with the previous plot.
Related
This question already exists:
Matlab subplots in loop: only shows plots in last iteration
Closed 3 years ago.
I'm trying to create a plot and layer multiple functions over each of the subplots. The output I'm getting, however, is only showing the final plot in each iteration. In other words, all subplots are filled with something, but only with the last curve that I 'added' (or at least I thought I did) -- the cyan curve. I tried using hold onin a number of different places, to no avail. Does anyone see what the problem might be?
%% Training phase
% Setting for plots
figure;
for tai = 1:length(training_algorithms)
% Create first subplot (and make sure we stay there)
subplot(3,2,tai);
% Plot the (sampled) sine function
plot(x,y,'bx');
hold on
colors = ['r', 'm', 'c'];
for nh = 1:length(num_hid)
net = networks{tai, nh}; % Load network
net.trainParam.showWindow = false; % Don't show graph
% Train network, and time training
tic;
[net, tr] = train(net, p, t);
durations(tai)=toc;
% Simulate input on trained networks (and convert to double format)
y_result = cell2mat(sim(net, p));
% Evaluate result
[slo, int, correlations{tai}] = postregm(y_result, y);
% Add network to array
networks{tai} = net;
% Plot network approximation results
plot(x,y_result,colors(nh))
ylim([-3 3])
title(training_algorithms{tai});
end
hold off
end
It looks like this has been answered already but it is also worth noting that even though you are setting the net.trainParam.showWindow property to 'false,' Matlab may still create a new figure and make it active even though it remains hidden. Then any plots you perform after that won't stack like you want unless you make the original plot active again.
For example, if you run the below code (I stripped out all of your specific functions but recreated the affect) you will see that at the end, there are 20 or so figures open but only 1 is visible. Uncommment the line towards the bottom in order to create the kind of stacked subplots you are after... Hope this helps.
Cheers.
% Training phase
% Setting for plots
f1=figure(1);
for i = 1:6
% Create first subplot (and make sure we stay there)
subplot(3,2,i);
x=0:.1:2*pi;
y=sin(x);
% Plot the (sampled) sine function
plot(x,y,'b');
hold on
colors = {'r', 'm', 'c'};
for j=1:3
f2=figure;
set(f2,'Visible','off');
y2=sin(x+j);
% Plot network approximation results
% figure(f1) % - uncommment me
plot(x,y2,colors{j})
end
hold off
end
figHandles = findobj('Type', 'figure')
I'm trying to plot a straight line from a point in x to different values of t, thereby making a line in a for loop. But I see no lines generated in my figure in MATLAB
Following is my code:
t=linspace(0,8,11)
xs=(1.+t).^0.5
x0=xs./(1.+t)
m=size(t)
n=max(m)
hold on
for k=1:n
plot(x0(k),t(1:k),'-')
hold on
end
Thanks
You do not need the loop to perform the plot.
plot(x0,t,'-')
Will work just fine! Unless you were attempting to plot points...use scatter() for that:
scatter(x0,t)
plot() and scatter() (and most of Matlab's functions) are meant to be used with vectors, which can take some time to get used to if you are used to traditional programming languages. Just as you didn't need a loop to create the vector x0, you don't need a loop to use plot().
You are adding one point in Y axis along a line in X Axis use this code
t=linspace(0,8,11)
xs=(1.+t).^0.5
x0=xs./(1.+t)
m=size(t)
n=max(m)
hold on
for k=1:n
plot(x0(1:k),t(1:k),'-')
hold on
end
for more fun and see exactly how for is performed use this for loop
for k=1:n
pause('on')
plot(x0(1:k),t(1:k),'-')
hold on
pause(2)
end
I have been trying to create a MATLAB GUI using Guide which :
i) has a function that takes in input parameters (Temperature, Superconducting Gap Energy, Broadening Parameter) and outputs a plot - a Density of States plot showing a superconducting energy gap.
Note: This function involves numerical double integration, so the parameters can not be varied in a straightforward manner by using sliders. To study the variation in the curve from different parameters, each time the new parameters are input, the function double integrates again and a new curve is generated within the same axes.
ii) The GUI has 4 sets of input fields so that 4 curves can be plotted within the same axes at at a given time for comparison.
I used the following code:
handles.P1=plot(handles.dIdV,bias1,cond1,'r','linewidth',2);
%P1 = plot(handles.dIdV,bias1,cond1,'r','linewidth',2);
hold on
%plot(x,data(:,2),'b','linewidth',2)
%scatter(E,XDOS)
%xlim([min(bias) max(bias)])
%title(nem)
(Kindly do not get confused by the comments. 'cond1' is the result of integration for set1 of parameters, this is plotted against the array 'bias'. Thus the DOS (function of bias, temperature, delta-gap value, etc) is integrated up to each 'bias' value and stored in 'cond1', which is then plotted against that 'bias' value. )
to clear this, I wrote:
% --- Executes on button press in clear1.
function clear1_Callback(hObject, eventdata, handles)
% hObject handle to clear1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.temp1=0;
handles.delta1=0;
handles.tao1=0;
handles.vmod1=0;
handles.val1=0;
hold off
i.e. all the parameters are reset to zero and hold function is turned off.
The same bit of code has been written 4 times for 4 different curves.
So each curve has a hold function when the plot command is given and when the clear button is pressed, the 'hold' is supposed to turn off.
e.g. Curve1 is generated using parameterset1. Pressing the clear1 button should turn hold off for curve1 so that new values can be put in parameterset1 and a new curve1 can be plotted on same axes as curve2, curve3 and curve4, without affecting these other curves.
There is a problem with the execution of the 'hold on' and 'hold off' lines in that I cannot delete one curve at a time and replace it with a new one.
The moment I enter new parameters into any of the handles, all the other plots disappear.
Where could I be going wrong?
Is it possible to replace one curve at a time in a single axis with hold on in MATLAB?
Thanks a lot.
Well that is how hold is supposed to work. If you would like to overwrite individual items, just reassign the data that each plot object holds. For example, if you want to replace the handles.temp1 object's data, it would look like:
set(handles.temp1, 'XData', (New xdata), 'YData', (new ydata))
%You might need a drawnow() here but not sure.
You can also update other line object properties the exact same way using set().
Also, note that hold never is off, because otherwise the next plot item will overwrite everything else.
Edit: I would also like to point out that setting handles.temp1 = 0 is not what you are trying to do. Note that a line object has "properties", which is really what you are trying to manipulate. See this for line properties. If you don't know anything about objects and OOP see this
that's a thing that is making me a bit crazy-noob so far.
I have my struct storing data from successive experiments, 7 field per each experiment:
veq1
rpmdispl1
displ1
tau1
sigma1
mu1
v_displ1
veq2
...
Then i'd like to plot in for loops, like (k is total datasets to be plotted)
figure(1)
hold all
for ii=1:k;
subplot(2,1,1)
eval(['plot(struct.displ',num2str(ii),',struct.tau',num2str(ii),')']);
subplot(2,1,2)
eval(['plot(struct.displ',num2str(ii),',struct.v_displ',num2str(ii),')']);
end
But actually I am not allowed in changing plot axes style among the plots of the loop. (using either roots or gca settings, line and color string variables, etc)
So i thought to do it in a different way, like:
for ii=1:k;
subplot(2,1,1)
plot(struct.displ(num2str(ii)),struct.tau(num2str(ii)),line,color)
subplot(2,1,2)
plot(struct.displ(num2str(ii)),struct.v_displ(num2str(ii)),line,color);
end
But no way. This last is only an idea (rather than a working code), I admit it. Can somebody suggest me something to work it out?
I'd be grateful.
Many of the plotting functions in MATLAB and toolboxes (thought not all) allow both the following syntaxes:
plotfcn(data1, data2, ...)
plotfcn(axes_handle, data1, data2, ...)
The first plots into the current axes (gca) or creates and plots into a new axes if none exists. The second plots into the axes with handle axes_handle.
Having looked into the internals of several MATLAB and toolbox plotting functions, it looks like there isn't really a standardised way that MathWorks do this. Some plotting routines use the internal, but open, function axescheck to parse the input arguments; some do a simple check on the first input argument; and some use a more complex input-parsing subfunction that can handle a larger variety of input syntaxes.
Note that axescheck appears to use an undocumented syntax of ishghandle - the doc says that ishghandle takes only one input, returning true if it is any Handle Graphics object; but axescheck calls it as ishghandle(h, 'axes'), which returns true only if it's specifically an axes object.
Is anyone aware of a best practice or standard for implementing this syntax? If not, which way have you found to be most robust?
In case anyone is still interested, four years after I posted the question, this is the pattern that I have mostly settled on.
function varargout = myplotfcn(varargin)
% MYPLOTFCN Example plotting function.
%
% MYPLOTFCN(...) creates an example plot.
%
% MYPLOTFCN(AXES_HANDLE, ...) plots into the axes object with handle
% AXES_HANDLE instead of the current axes object (gca).
%
% H = MYPLOTFCN(...) returns the handle of the axes of the plot.
% Check the number of output arguments.
nargoutchk(0,1);
% Parse possible axes input.
[cax, args, ~] = axescheck(varargin{:});
% Get handle to either the requested or a new axis.
if isempty(cax)
hax = gca;
else
hax = cax;
end
% At this point, |hax| refers either to a supplied axes handle,
% or to |gca| if none was supplied; and |args| is a cell array of the
% remaining inputs, just like a normal |varargin| input.
% Set hold to on, retaining the previous hold state to reinstate later.
prevHoldState = ishold(hax);
hold(hax, 'on')
% Do the actual plotting here, plotting into |hax| using |args|.
% Set the hold state of the axis to its previous state.
switch prevHoldState
case 0
hold(hax,'off')
case 1
hold(hax,'on')
end
% Output a handle to the axes if requested.
if nargout == 1
varargout{1} = hax;
end
not sure I understand the question.
What I do is to separate the plotting of data from the generation / setup of plots. So if I want to plot a histogram in a standardized way I have a function called setup_histogram(some, params) which will return the appropriate handles. Then I have a function update_histogram(with, some, data, and, params) which will write the data into the appropriate handles.
This works very well, if you have to plot lots of data the same way.
Two recommendations from the sideline:
Don't go undocumented if you don't need to.
If a simple check is sufficient, this would have my personal preference.