White lines in figure after exporting to PDF - matlab

A 2D data matrix was plotted in MATLAB 2016a using contour (the first Figure below), and then I saved as the figure in the *.emf format. Next, I inserted the figure (emf) into a MS word document. And finally, the word document was converted to a pdf file.
I found that there are many white lines in the figure (when in a pdf format) as shown in the second figure below. My question is how can I remove those white lines?
The code is attached here:
path = 'C:\Users\Administrator\Desktop\';
data = importdata([path, 'lsa2.txt'], ' ', 6);
cdata = data.data;
n = 25;
contourf(cdata,n, 'LineStyle', 'none');
colormap(jet);
axis equal;
The data can be accessed here: https://www.dropbox.com/s/hzf75qiju6zsy9i/lsa2.txt?dl=0

As I mentioned in my comment, this is a bug with the way MATLAB exports graphics, as explained by Yair Altman and Dene Farrell:
I discovered that these white line artifacts happen when the painters renderer is used ... [which] is the default rendering [format engine] for vectorized (EPS/PDF) formats.
There are two separate issues with the Matlab export:
1. The main thing that everyone notices is that patches are broken up into triangles, each of which is a separate path object if inspected in illustrator.
2. Matlab sometimes adds extraneous 'cropping paths' that create an apparent white line even when there is no issue with fractured paths.
One workaround suggested there by ambramson is the following:
1. Save the figure as an .eps file (using the print command).
2. Using a text editor, change the line in the eps header from:
/f/fill ld
to:
/f{GS 1 LW S GR fill}bd
and move the line down several lines, to right below the /LW/setlinewidth ld line.
From here, your eps file should display fine on all pdf viewers.

Related

Exporting and printing matlab figure [duplicate]

This question already has answers here:
Saving MATLAB figures as PDF with quality 300 DPI, centered
(2 answers)
Closed 2 years ago.
I have a Matlab figure. I need to use it as a picture so I can insert it in Word, then save that new Word document as a PDF file and then print that PDF file. I have tried saving Matlab figure as .JPG and . PNG file but the picture gets "smaller" when inserted in Word and converted to PDF and when printed, you can hardly distinguish anything. What can I do so that the quality of the figure dosen't change?
You have a couple of options here.
Specify the Resolution
When saving the figure, by default 72 dpi is used (your screen resolution) which may causeyour images to appear small when being inserted into a Word document. Rather than using saveas, you can use print to specify the resolution of the resulting image. For a PNG
print(hfig, 'filename.png', '-dpng', '-r300') % Resolution = 300 DPI
Note that if you're using print, you will also need to specify a few other properties of the figure to get it to look similar to the on-screen appearance.
set(hfig, 'Units', 'inches');
pos = get(hfig, 'Position');
set(hfig, 'PaperPositionMode', 'manual', ...
'PaperPosition', [0 0 pos(3:4)], ...
'InvertHardCopy', 'off');
Use an EPS
If you're ultimately exporting to a PDF and your image is line art, consider exporting to an EPS (a vector-graphic). Again, this can be done using print.
print(hfig, 'filename.eps', '-depsc2')
Use export_fig
The FEX submission export_fig is a widely-recommended utility for creating figures from your MATLAB figures in a way that preserves the way that they appear within MATLAB.
You don't need to save it as a file, just copy it to the clipboard and then paste it, it will be copied as a metafile (vector graphics) that looks good when resized. It is best to resize by dragging the corners to maintain the original aspect ratio.
After you make a figure, select from the figure menu: Edit / Copy Figure and then paste into Word or PowerPoint. You can change some of the options for copying by selecting Edit / Copy Options... from the figure menu

Triangular split patches with painters renderer in MATLAB 2014b and above

MATLABs new graphics engine, HG2, fails to properly print patches using the painters renderer:
hist(randn(1,1000));
colorbar('Location','SouthOutside');
print('test.pdf','-dpdf');
The resulting patches, whether generated by hist or colorbar, have triangular splits:
The issue has been discussed on MATLAB Central here and here, where it was suggested that disabling the "smooth line art" option in the pdf-viewer should solve it. This conceals the problem in some readers (e.g. in Adobe Reader but not in Apple Preview), but it is hardly a solution to ask collaborators and readers to use a specific pdf-viewer with non-default settings for graphics to appear correctly. Looking at the resulting file in Inkscape, it is clear that the split is present in the output vector graphics. Here, I moved one half of the colorbar, proving that it is in fact split in half, and not just misinterpreted by the pdf-viewer:
The problem is not present using the OpenGL renderer (print('test.pdf','-opengl'), but then the output is not vectorized). The problem persists in MATLAB 2015a.
Is there a way to export artifact-free vector graphics in MATLAB 2014b or later?
Here's a questionable work-around until the actual problem is solved:
The diagonal lines are simply the empty space between the triangles, so what we are seeing is the white space behind the patches peek through. Silly idea:
Let's fill that space with matching colors instead of white.
To do so, we'll copy all objects and offset the new ones by just a tiiiiny bit.
Code:
hist(randn(1,1000));
colorbar('Location','SouthOutside');
print('test.pdf','-dpdf'); %// print original for comparison
f1 = gcf;
g = get(f1,'children');
n = length(g);
copyobj(g,f1); %// copy all figure children
The copied objects are now the first n elements in the 2*n f1.Children array. They are exactly on top of the old objects.
g=get(f1,'children');
for i=1:n;
if strcmpi(g(i).Type,'axes');
set(g(i),'color','none','position',g(i).Position+[0.0001 0 0 0]);
set(g(i+n),'position',g(i+n).Position); %// important!
end;
end;
print('test2.pdf','-dpdf');
Explanation:
g = get(f1,'children'); gets all axes, colorbars, etc., within the current figure.
colorbar objects are linked to an axes, which is why we'll only have to move the axes type children.
Setting the color to none makes the background of the new axes transparent (since they are on top of the old ones).
g(i).Position+[0.0001 0 0 0] shifts the new axes by 0.0001 normalized units to the right.
set(g(i+n),'position',g(i+n).Position); This line seems unnecessary, but the last image below shows what happens when printing if you don't include it.
Depending on the types of graphics objects you have plotted, you may need to tweak this to fit your own needs, but this code should work if you have only colorbar and axes objects.
Original:
With hack:
Without %// important! line:
In R2015b, histogram seemed to not show the white lines, but fill did.
For simple plots just paste the data again:
x = 0:pi/100:pi;
y = sin(x);
f = fill(x,y,'r');
hold on;
f2 = fill(x,y,'r'); %// Worked like magic
If the magic fails try similar to Geoff's answer: f2 = fill(x+0.0001,y,'r');
Depending on what version of Matlab you are using, you might try to use epsclean. It doesn’t seem to work with very recent versions of Matlab like 2017a.
Otherwise, epsclean can be run on an existing eps file (not pdf) exported with the -painters option to generate a vectorized figure, and it will rewrite (or create another file) with those white lines removed.

Jagged outline using Matlab 2014b

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.

How to render MATLAB figure legend texts as LaTeX?

Although I have rendered my legend text with LaTeX in MATLAB as follows
set(myLegend, 'fontsize', 8, 'interpreter','latex', 'Position', [0.67, 0.12, 0.3, 0.01]);
I still feel that the texts are rather different from my main texts. For example, the texts seem so ugly, because the letters are too far apart. Plus, the strikes are so thin.
How can I make them look exactly the same as the caption below?
You can actually export your Matlab figure by using Matlab2tikz. Once you get your Matlab figure, just insert it in your LaTeX file by \input{myfigure.tex}.
Using Matlab2tikz is really easy, as stated in the README file:
The workflow is as follows.
a. Place the matlab2tikz scripts (contents of src/ folder) in a directory
where MATLAB can find it (the current directory, for example).
b. Make sure that your LaTeX installation includes the packages
TikZ (aka PGF, >=2.00) and
Pgfplots (>=1.3).
Generate your plot in MATLAB.
Invoke matlab2tikz by Matlab matlab2tikz(); or matlab2tikz('myfile.tex');
The script accepts numerous options; check them out by invoking the help, help matlab2tikz Sometimes, MATLAB makes it hard to create matching LaTeX plots by keeping invisible objects around or stretches the plots too far beyond the bounding box. Use Matlab cleanfigure;matlab2tikz('myfile.tex');` to first clean the figure of unwanted entities, and then convert it to TeX.
Add the contents of myfile.tex into your LaTeX source code; a
convenient way of doing so is to use \input{/path/to/myfile.tex}.
Also make sure that at the header of your document the Pgfplots package
is included
This should be in your .tex file:
\documentclass{article}
\usepackage{pgfplots}
% and optionally (as of Pgfplots 1.3):
\pgfplotsset{compat=newest}
\pgfplotsset{plot coordinates/math parser=false}
\newlength\figureheight
\newlength\figurewidth
\begin{document}
\input{myfile.tex}
\end{document}
This is how I normally embed latex in legends,
l = legend('$\alpha$', '$\dot{\alpha}$', '$x$', '$\dot{x}$');
set(l, 'interpreter', 'latex', 'location', 'northwest', 'FontSize', 15)
For some reason, possibly a bug, it only works when when you set the interpreter via the object's setter.
To do the above caption try,
l = legend('(b) $t=9:00 \Delta t$
set(l, 'interpreter', 'latex')

make grid lines bigger in matlab figures

How can I make grid lines bigger (more fat for printing purpose) in my matlab figures?
I'm including matlab figures in to my .tex document after using the following
print -depsc testFig.eps
to convert the figure into .eps for inclusion in my .tex doc.
But my grid lines don't look good at all. i.e they appear faint when I print the document. Is there anyway I can increase the size/width of the grid lines?
If you use
set(gca,'LineWidth',10)
after "grid on" this should increase the boarders of all axes, including the grid lines.