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.
Related
I am plotting some maps using Matlab that use mapshow to plot the country border from a shapefile. I then export them to both a PDF and EPS format using the export_fig package. This worked completely fine using Matlab 2014a, but I have just upgraded to Matlab 2014b to take advantage of something else that has improved, and now my country border is all jagged. The border only looks jagged on the saved versions of the file. If I zoom in on the figure window, the outline isn't like that.
Here are the snippets of code that are important. It is a custom shapefile, so I don't know how to put it on here so people can replicate it.
This bit reads in the shapefile and plots it. The display type is 'polygon' if that is relevent, hence getting rid of the 'FaceColor' so I can see what I am plotting underneath (the green bits in the background of the images, plotted using pcolor).
thaiborder=shaperead('Thailandborder');
mapshow(thaiborder,'FaceColor','none');
This bit is how I am exporting the figure.
export_fig test.eps -r600 -painters
export_fig test.pdf -r600 -painters
This is the version with a smooth border from Matlab 2014a:
This is roughly the same area of the image, with the jagged border from Matlab 2014b:
Does anyone know why these differences are occurring? I want the border to be like it is in the first image, but I need the "improved" functionality of Matlab 2014b for another thing in the same image. What do I need to change?
Edit to add: I have been in contact with the creator of export_fig and he thinks it is caused by Matlab now using mitred joins rather than round ones. Apparently I have to write to MathWorks to complain. I didn't put this as an answer because someone else may be able to provide a solution for me.
Matlab acknowledged that this is known bug. For me the first fix worked.
The issue of jagged lines on the figures while exporting in the vector format is a known bug in MATLAB R2014b. It is associated with the combination of linejoins and meterlimits used in vector format.
To work around this issue, use the attached function fixeps to post process the EPS file.
You can use one of the following ways to call this fixeps function.
fixeps('input.eps','output.eps','LJ') % Will change the linejoins to round
fixeps('input.eps','output.eps','ML') % Will correct the miterlimit
function fixeps(inname,outname,fixmode)
if nargin==2
fixmode = 'LJ';
end
fi = fopen(inname,'r');
fo = fopen(outname,'w');
tline = fgets(fi);
while ischar(tline)
if (strcmp(tline,['10.0 ML' 10])) % Replace 10.0 miterlimit
switch (fixmode)
case 'LJ'
fwrite(fo,['1 LJ' 10]); % With round linejoin
case 'ML'
fwrite(fo,['2.5 ML' 10]); % With smaller miterlimit
end
else
fwrite(fo,tline);
end
tline = fgets(fi);
end
fclose(fo);
fclose(fi);
I had a similar problem that I found to be caused by the 'MarkerSize' option. It seems that in version 2014b it inherits the units of the figure. For example, if I have a figure in centimeters and I ask for ('MarkerSize', 10), the 10 will not be interpreted as points (as in 2014a) but as cm. I fixed this by changing the figure units to pt.
I have used drawnow to draw the characters of the mnist dataset.. which outputs the following output
when i created GUI with matlab and calling drawnow to display images after loading it draws the figure on the open window giving the following output
my question is how to force it to draw in new window ?
drawnow only asks Matlab to flush the event queue and update figure windows; it doesn't determine how and where things are plotted. It's hard to tell since you don't include any code, but in your case it looks like you just plot the character images and the GUI elements into the same figure.
You can control which figure window a graphics operation refers to by setting the "current figure", whose handle is always contained in the variable gcf (graphics: current figure).
You generate a new figure and make it current by calling
figure
If you want to later make this figure current again, you need to save its handle:
fa = figure;
You then make a figure with a given handle current again by
figure(fa)
Some rough sketch of a possible program:
% generate figure windows
fa = figure;
fb = figure;
% plot something in figure a and make the screen update
figure(fa)
plot(...)
drawnow
% put a UI element into figure b and make the screen update
figure(fb)
uicontrol(...)
drawnow
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');
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.
Usually when I plot in MATLAB, it always draws on the same figure. How do I make it draw in a new figure?
I know it is pretty elementary, but I'm not finding it using Google Search.
figure;
plot(something);
or
figure(2);
plot(something);
...
figure(3);
plot(something else);
...
etc.
While doing "figure(1), figure(2),..." will solve the problem in most cases, it will not solve them in all cases. Suppose you have a bunch of MATLAB figures on your desktop and how many you have open varies from time to time before you run your code. Using the answers provided, you will overwrite these figures, which you may not want. The easy workaround is to just use the command "figure" before you plot.
Example: you have five figures on your desktop from a previous script you ran and you use
figure(1);
plot(...)
figure(2);
plot(...)
You just plotted over the figures on your desktop. However the code
figure;
plot(...)
figure;
plot(...)
just created figures 6 and 7 with your desired plots and left your previous plots 1-5 alone.
The other thing to be careful about, is to use the clf (clear figure) command when you are starting a fresh plot. Otherwise you may be plotting on a pre-existing figure (not possible with the figure command by itself, but if you do figure(2) there may already be a figure #2), with more than one axis, or an axis that is placed kinda funny. Use clf to ensure that you're starting from scratch:
figure(N);
clf;
plot(something);
...
As has already been said: figure will create a new figure for your next plots. While calling figure you can also configure it. Example:
figHandle = figure('Name', 'Name of Figure', 'OuterPosition',[1, 1, scrsz(3), scrsz(4)]);
The example sets the name for the window and the outer size of it in relation to the used screen.
Here figHandle is the handle to the resulting figure and can be used later to change appearance and content. Examples:
Dot notation:
figHandle.PaperOrientation = 'portrait';
figHandle.PaperUnits = 'centimeters';
Old Style:
set(figHandle, 'PaperOrientation', 'portrait', 'PaperUnits', 'centimeters');
Using the handle with dot notation or set, options for printing are configured here.
By keeping the handles for the figures with distinc names you can interact with multiple active figures. To set a existing figure as your active, call figure(figHandle). New plots will go there now.
Another common option is when you do want multiple plots in a single window
f = figure;
hold on
plot(x1,y1)
plot(x2,y2)
...
plots multiple data sets on the same (new) figure.
As simple as this-
figure, plot(yourfigure);