I noticed that if I have Matlab code where my figure has to display a legend, the running time increases significantly.
Here's an example:
clear all
close all
clc
% legend test
x = [0:1:100];
y = x.^(3.123);
figure('Name', 'X-Y and X-X plot')
plot(x,y)
hold all
plot(x,x)
legend('1', '232')
Gives a running time of 1.1 seconds. Same code without the legend('1', '232') line has an execution time of 0.4 seconds. I find it very odd that a simple legend increases the running time this much.
With the profiler I found that the function mainly responsible for the time increase is called graphics/private/texmex. It has a self-time of 0.12 seconds and is called 4 times. When I don't create a legend this function is not called.
Is there a way to speed up my code, while still generating a legend in a figure?
I'm running 64-bit Matlab 2012b on Mac OS 10.8.3.
When I run the code in the example with set(0, DefaultTextInterpreter, 'none') the texmex function is called by tex>localCallTeXParser, which is called by scribe.legend.methods>strsize, etc...:
graphics/private/texmex
tex>localCallTeXParser
scribe.legend.methods>strsize
scribe.legend.methods>getsizeinfo
scribe.legend.methods>getsize
scribe.legend.methods
scribe.legend.legend
I had the same issue with a project of my own. I wanted to dynamically update some line plots quickly using a slider, but noticed that the having a legend active really killed the performance I was getting.
I found the solution to my problem here - http://undocumentedmatlab.com/blog/plot-performance/.
From the second listed performance hack, I added the lines
set(gca,'LegendColorbarListeners',[]);
setappdata(gca,'LegendColorbarManualSpace',1);
setappdata(gca,'LegendColorbarReclaimSpace',1);
to my code. I got an error message for the first line of code that was mentioned, so I struck it out above. Regardless though, the other two lines of code made my plots update just as quickly with a legend as they did without the legend being present.
Sounds like legend is using a TeX interpreter (at least, that's what texmex sounds like). In that case, you could try
legend({'1', '232'}, 'Interpreter', 'none');
This will disable the TeX interpreter and therefore may improve the performance. I should probably note that I've never experienced any trouble with the speed of the legend function, so it's probably something specific to your plots and/or MATLAB installation/version.
Edit: I have the feeling that the above will draw the legend with the TeX interpreter first, then disable it and draw it again. Try doing the following before drawing the legend or perhaps before drawing the figure (not sure at which point MATLAB will promote the default properties to an actual figure / axes / legend):
set(0, 'DefaultTextInterpreter', 'none');
Related
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)
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
As the title states, the colorbar in surface plots does not appear when the default interpreter is set to 'latex'. This occurs in MATLAB 2012b and 2013a and on two different machines.
Precisely, the colorbar object is created, can be clicked when editing the plot, can be edited using the interactive colorbar editor but is not visible at all.
It does not appear when saved as a figure and reopened, saved as a PNG, exported in .eps format or saved as a .pdf.
After searching around, I found the following post from 2011, concerning MATLAB 7:
http://mathforum.org/kb/message.jspa?messageID=7518470
Specifically, the interpreter appears to be at fault, when it is set to 'latex', the colorbar will not display. When set to the default, it does.
Here is the smallest demonstrating example.
set(0,'defaulttextinterpreter','none');
figure;
surf(peaks(100)); colorbar
set(0,'defaulttextinterpreter','latex');
figure
surf(peaks(100)); colorbar
The two figures are identical except that the colorbar is visible only in the first figure.
I use a lot of special characters and sub/superscripts in my plots so in startup.m I set the default interpreter to 'latex'. I could surround all calls to colorbar with:
set(0,'defaulttextinterpreter','none');
colorbar;
set(0,'defaulttextinterpreter','latex');
But this is probably the least elegant solution possible. Can anyone shed some light on this issue which appears to be extant for over 5 years and multiple editions of MATLAB?
This behaviour is gone in Matlab R2014b, which uses an entirely new graphics engine, hg2. The plots look different (most of the time in a better way), but instead of old, documented bugs, there are now new, undocumented bugs...
Earlier versions of Matlab support somewhat experimental stages of hg2. You can enable these by running Matlab with the switch "-hgVersion 2". You can do this, for example, by editing the Desktop shortcut to point to something like "C:\Program Files\MATLAB\R2013b\bin\matlab.exe" -hgVersion 2.
Unfortunately, with the new graphics engine being the default in Matlab2014b, the old bugs are less likely to be fixed in the future. I wish I could help you in a better way, but the workaround you posted seems like a good solution, especially if you wrap it in a function called robust_colorbar or so.
I can reproduce the problem on my system (R2010b, Windows Vista 32 bits) . It seems to be solved by changing the 'Renderer' property of the figure from the default 'OpenGL' to either 'painters' or 'zbuffer'. So, you can either change the renderer when creating the figure:
set(0, 'defaulttextinterpreter', 'latex');
figure('Renderer', 'zbuffer') %// this line changed
surf(peaks(100)); colorbar
or change the default renderer to be used for all figures (so you don't need to change it in every figure):
set(0, 'DefaultFigureRenderer', 'zbuffer'); %// this line added
set(0, 'defaulttextinterpreter', 'latex');
figure
surf(peaks(100)); colorbar
Using a renderer other than 'OpenGL' may affect features such as transparency or drawing speed. Here's some information about pros and cons of each renderer.
As MATLAB has changed its figure engine in R2014b I decided to rerun some of my code for getting better looking figures out of them. Unfortunately, the last one I have is a code that takes ages to run, and I would like to highly avoid to rerun the code for a nicer figure.
I saved the result in a .fig file in R2013b. However, if I open it in R2014b, it still has the old format.
Is it possible to redraw the figure using the MATLAB R2014b plotting engine? If it is, how could I do it?
NOTE: Literally, the figure is opened and drawn with the new engine, however, it retains its old format. While a new figure with a title() command would plot a nice big, bold title, if a redraw this figure using "drawnow" or I generate code for it, the format remains the same.
Example: This figure was created in 2013b, and redrawn in 2014b. You can see that the title does not plot in the same format as a title('whatever') would plot in the new graphic handles. It looks like that a '.fig' saves and sets the default values for the version it has been generated. Thus plot colors, titles, labels etc will look like the old graphic handles when redrawn.
This can be tested with the following code. Note that this is an overly simplified problem, the question is not explicitly about titles or labels, but all graphic stuff in general.
rng(1)
figure()
x = 1:50;
y = rand(1, 50);
plot(x,y)
title('this NICE Title')
xlabel('labels!')
ylabel('some other labels','Interpreter','Latex')
If this code is run in 2013b and 2014b, saved as fig in both and then opened as fig in both, the next 2 figures appear:
The 2013b fig file: http://s000.tinyupload.com/index.php?file_id=02053933004513599550
There is a roundabout way for doing this -- just using hgopen for loading the figure and then extracting the data to re-plot it in 2014b:
h1=hgopen('test.fig'); % h1 = handle to the figure
allaxes=get(h1,'children'); % allaxes = array with axes handles
for a=1:length(allaxes)
ax=allaxes(a);
allines=get(ax,'children'); % all lines in current axes
for l=1:length(allines)
lin=allines(l);
values=get(lin,'ydata'); % values of the current line
subplots{a}{l}=values;
end
end
You can then use the subplots cell array to make the plots again by hand. It is a boring way to do it, but may be worth trying if re-generating the output takes very long.
I have a code with a lot of plots. The problem (excuse my ignorance because I don't know if it's possible) is, for example, when I execute since the beginning, I directly see the last plot, not one after the other. So, for example, I've tried this but it doesn't work at all:
pause(2); %After two seconds it starts and open the plot but I directly see the last plot, not this
plot (x, y);
title ('Average values')
close; % The command close it works but only if I press 'evaluate function'
pause(2);
plot (out1,out2);
close;
Also, I've tried with the keyboard command to try if it's possible to close the plot with one key and then, open the other with another key but I couldn't do it.
If someone knows how can I do it I will be so I'll be so grateful,
Matlab does plotting and the calculation typically in the same process. So typically you will not get anything displayed till there is some spare time for plotting in your program.
To force matlab to redraw the windows you can use the drawnow command. But it only draws exactly at the moment - so if your figure window would be hidden or behind some other window, the redrawing when it comes to foreground will not happen till the next time.
In your case you also close the plot before the pause (where it could be displayed). So if you'd exchange the two commands you should see it. The obvious drawback of the pause is - it halts your program for the time.
from my experience I would suggest you rather save the plots as graphic files and use some external program to view them.
Also I find the popping up new windows annoying and interrupting my workflow - so I would reuse the graphic window, by just clearing it with clf.
I may misunderstand what you are trying to do, but when i try to create what you describe it just works for me as expected. Here is my example:
Note that you will want to close any open figure windows to ensure that it pops up rather than letting it stay in the background.
pause(2); % Wait 2 seconds before starting
plot(1:10); % Plot an upward line
title('up'); % Give it a title
pause(2); % Wait 2 seconds before showing the next plot
plot(10:-1:1); % Plot an downward line
title('down'); % Give it a title
Depending on how you want to use them, saving the plots may be a nicer solution.