# How to include SVG diagrams in LaTeX?

I'm making all my diagrams in SVG format using Inkscape and then I export them to some other format (e.g. PDF, EPS or PNG). I wrote a short script that does this for me automatically, but I'd like to avoid this step, if possible --- sometimes the conversion from SVG converts the text labels into vectors, and that's annoying. Hence the question:

Is there a way to include SVG diagrams directly without conversion to an intermediate format?

Package suggestions, or instructions for specific LaTeX distribution are welcome. Tips and personal experience on which tools you have found to be working reliably would be also appreciated.

• What types of diagrams are you creating with Inkscape? Maybe you could do them via TikZ or gnuplot. The latter offers a special LaTeX-export, thereby allowing you to use mathmode for labels etc. – Bran the Blessed Aug 20 '10 at 18:09
• TBH, I've never used TikZ so far, but I guess it's time to give it a try for the next paper. I make all kinds of diagrams, mostly engineering-oriented (e.g. free-body diagrams, component loads and such), but sometimes more generic boxes-and-arrows stuff. – Martin Tapankov Aug 20 '10 at 18:19
• Good question. But is exporting text labels as vectors is always annoying? – Orion Nov 4 '13 at 11:57

The latest version of Inkscape supports PDF+LaTeX export. The graphic itself is exported as PDF, but all text can be put into a .tex file. This way all the text appears in your document font.

The latest Inkscape version can be found on the SourceForge Project site (v0.48).

There is also a free article about the export on CTAN: How to include an SVG image in LaTeX.

From that article, the quickest way to get this done is:

inkscape -D -z --file=image.svg --export-pdf=image.pdf --export-latex


Then include the generated TeX file, which will automatically import the image:

\begin{figure}
\centering
\def\svgwidth{\columnwidth}
\input{image.pdf_tex}
\end{figure}


Be aware that this uses \includegraphics to insert the graphic, so you need to include graphics or graphicx in your document.

Further, here are two good things that I found over time of using this feature. Both are mentioned in the linked pdf, but I missed those hints for quite some time.

When you insert text, there is a little square in the textbox which shows you the alignment of the text. For example if you want to have an arrow pointing from your text to an object, make sure the justification is correct.

For some time I was thinking, that text could not handle line breaks, but it is possible if you flow text into a shape. Draw a rectangular shape, write some text, select both and then go in the text menu to "Flow into frame". The shortcut for this is Alt + W.

• This is the same what Bran has written in the first comment. – Martin Tapankov Aug 20 '10 at 20:08
• By the way, Inkscape 0.48 is now officially released, so it is not an alpha version any more. The LaTeX export feature is now an official feature of Inkscape. – Jan Hlavacek Feb 23 '11 at 15:43
• This tool is really nice, but you do need to be careful about scaling - you can set \svgwidth but the text is then positioned correctly but not scaled, or you can wrap the whole \input in a \resizebox which scales the text correctly - often to too small. – Chris H Sep 10 '13 at 10:48
• True @ChrisH, what I did is to adjust my font in inkscape to have the correct width (compared to my LaTeX font) and I create my graphics at nearly the correct size (-> textwidth from latex). That way you avoid surprises later on. You can also just write \small or \footnotesize in front of the import or input command to scale the font if necessary. – Martin H Sep 10 '13 at 13:33
• This is clearly not an answer to the question. If the SVG file is originating from any programme other than Inkskape the extra conversion is still required. Moreover, there is nothing in this solution concerning direct inclusion of SVG files in tex documents. – Luís de Sousa Dec 10 '14 at 19:35

There is now (at time of writing for about a month) a package svg on CTAN and also included into the big TeX distributions.

This package makes use of pdfTeX primitives. Not all of these are defined in LuaTeX, so you would get errors on compiling. See answer of Heiko Oberdiek for a solution.

Every SVG file given by the command \includesvg will under the hood be converted with the help of some additional programs, which at least on Windows are not installed by default (the package claims, it wouldn’t run in Windows, but see below):

• ImageMagick (actually the included convert)
• only MiKTeX users: Xpdf (actually the included pdftops)

Notes:

1. For compilation pdflatex needs the command line switch --shell-escape.

2. All executables/binaries must be located in the search path. In Windows only the “ImageMagick” installer does this by default. For inkscape and pstopdf one needs to add the paths oneself, or I would recommend for each a batch file in the binary path of your local texmf tree (which anyway should be itself in the search path). Additonal hint for MiKTeX users: Create a local texmf tree in MiKTeX.

inkscape.cmd (it must get this name!):

@echo off
<path-to-inkscape>\inkscape.exe %*


pdftops.cmd (it also must be named this way!), not needed for Users of TeX Live:

@echo off
<path-to-Xpdf>\pdftops.exe %*


3. The package uses the *nix specific commands mv and rm. In Windows we can emulate them once more with batch scripts, which again must get the names given here and should be put into the bin folder of the local texmf tree:

mv.cmd:

@echo off
move /Y %*


The switch /Y overwrites existing files without any question! I introduced it here for the use with TeX editors.

rm.cmd:

@echo off
del /Q %*


The switch /Q also suppresses any question!

• Very useful information indeed (for miktex users) :-) – user11232 Nov 12 '12 at 1:50
• This should actually be the top answer because answer actually answers the question of "how to include SVG without converting". – user1271772 Aug 4 '14 at 11:30
• @user1271772: Thank you for this implicit compliment, but in fact also with this package the svg files are converted, but this happens under the hood during the compilation process. – Speravir Aug 4 '14 at 15:29
• @cfr Nope, there are other modes. You can have a make file to run afterwards, or a list of figures. – Raphael Apr 30 '15 at 10:14
• Any chance an example tex-file could be added to this answer? I have the texlive-recommended package on ubuntu but pdflatex errors out on \includepackage{svg} – PureW Sep 20 '16 at 17:41

As the other answers already mention, the TeX backends do not support the SVG file format. That means there is no other way than to convert the SVG images.

However, ConTeXt provides transparent conversion (complete list: ConTeXt Dependencies) of several file formats that are not natively supported by LuaTeX, e.g.:

• converting PostScript images to PDF
• converting GIF and TIFF images
• converting SVG and compressed SVG

The SVG conversion is done in the background using inkscape. This means from the users' point of view there is no difference if a PNG or a SVG file is included. Example:

\starttext
\externalfigure [image.svg]
\stoptext


A single compilation run with context file creates the temporary image m_k_i_v_image.pdf which is inkscapes output and is transparently included.

Result of the code above (a file only containing the SVG image image.svg):

• ohhh... +1 for the fancy graphics. – naught101 Apr 29 '12 at 6:31
• "... there is no difference if a PNG or a SVG file is included." Is'nt PNG rasterized? Shouldn't it be PDF? Otherwise that would be a shame. – Fictional Jan 28 '15 at 11:17
• @fictional: There is no difference from the user's point of view. That means you can include an SVG in the same way you'd include a PNG, and there's no special command that only works with SVG but not with PNG, assuming you use ConTeXt. – Zak Jul 30 at 8:39

If you figures are sufficiently simple TikZ 2.0 provides the SVG path operation:

\path . . . svg[<options>] "<path data>" ... ;


See the pgfmanual section 14.12. Only SVG 1.1 path data is supported.

Inkscape has a(n experimental) tikz exporter: link. (I've never used it but perhaps someone who has will stop by and give a few more details.)

• Isn't it only for paths? – Łukasz Lew Aug 21 '10 at 14:08

For including the SVG in LaTeX, you can refer to Marin H answer. But as Latex does not natively support SVG, you may run in to font size and placement issues. During the conversion from SVG to LaTeX as Inkscape carries out, all the positions are changed to absolute X, Y values, thus your alignments are lost in the conversion, as it does not recognize it.

Unless you exactly use the same LaTeX font size/type in Inkscape you will get a different output from what you see in inkscape. I gave up this route due to these problems and went for the normal SVG->PDF inclusion.

The example below illustrates the problem. The file inkscape-pdf.pdf_tex is generated using the PDF+LaTeX option in Inkscape.

The original Inkscape figure:

\documentclass{article}
\usepackage{graphicx,xcolor}
\begin{document}

\begin{figure}
\centering
\def\svgwidth{\columnwidth}
\input{inkscape-pdf.pdf_tex}
\end{figure}

\begin{figure}
\centering
\def\svgwidth{0.5\columnwidth}
\input{inkscape-pdf.pdf_tex}
\end{figure}

\end{document}


LaTeX output:

You may also want to look at Ipe. It is a graphics editor similar to Inkscape, but integrates tightly with LaTeX, and exports eps and pdf files that are easy to include into TeX documents. It also comes with a svgtoipe script that converts many svg figures to the ipe format, so that they can be edited with Ipe. I'm not sure how well does the conversion handle text, but it is easy to add the necessary labels in Ipe, and since Ipe uses LaTeX to render text, you can have your labels match your text perfectly.

• It not just exports to PDF, it saves the entire image as a PDF (or EPS). All Ipe data is inside that PDF, so you can just reload the PDF in Ipe and edit it if you want to change your drawing. Basically, the file you edit is the same file as you include in LaTeX, so no need to do an export each time you change the file. – Gijs van Oort Nov 20 '14 at 14:54
• Never heard of this software, very interesting suggestion, thank's. The ability to save all data required to edit the image later directly inside the PDF/EPS is quite attractive and would remove the need to have duplicate files (one in the original editable format and one EPS output, like when working with Inkscape or Gimp). – gaborous May 31 '16 at 17:17
• Simple, elegant, effective. This piece of software which I never even heard of is the answer to all my problems. Beautiful! Just beautiful! – PaulB Jul 24 at 13:28

Some additional information concerning Andrew's answer. As far as I know, LaTeX does not support including SVG files directly.

As this questions is still one of the first hits for "svg latex" I would like to add something to this topic.

• You can't directly include svg vectorgraphics. You have always to convert them.
• Conversion at the moment is easiest possible with inkscape, because it offers access to this functionality via command-line.

To make it short: use the svg-package by Phillip Ilten and see this blog post on laclaro.wordpress.com for examples and more features.

The longer story: It all started some time ago, when "Oni" wrote a python script, designed as inkscape extension to convert svg to tex+pdf (can still be found on the net). Today this plugin is a standard inkscape export option. The inkscape developers provided a document how to manually use this new feature from a latex document (called svg-inkscape).

Based on that I wrote about including SVG in LaTeX documents, and added some bits to the includesvg command and some months later there was the "svg" package published by Philip Ilten, which I recommend everyone to use. Some extended examples, merging my work and that of Philip can be found on http://laclaro.wordpress.com.

Having read your comment, maybe a combination of Inkscape and the overpic package may be helpful. This package allows you to write any LaTeX commands on top of an existing picture. A colleague of mine uses it to draw pictures of free-form curves, for example, and adds all labels and points of interests manually. The package allows you to display a grid, so it should not be too tedious---depending on the size of your picture, of course.

There are several SVG → PDF converters available, e.g. Apache Batik's rasterizer.

• It's a shame they called it a rasterizer! – Joseph Wright Aug 21 '10 at 12:24
• Why is it a shame? I have ever used it therefore I asked. – lazyboy Oct 2 '12 at 19:20
• @lazyboy because rasterisation denotes the act of converting a vector graphic (where shapes are given by coordinates) into a raster format (typically described by its pixels or similarly lossy data), but pdf is able to contain vector graphics. So the rasterizer does more than just rasterize. – Bruno Le Floch May 22 '13 at 16:48

With great thanks to the work of laclaro and Philip Ilten, I suggest the following alternative.

I want to do something just very slightly different - I don't want LaTeX to do the text for me, as the text in my figures is often rather tightly sized/positioned, and I have a preference (on the basis of readability, not aesthetics) for sans serif in figures, especially when there is vertical or very small text. So here's the code:

\newcommand{\executeiffilenewer}[3]{%
\ifnum\pdfstrcmp{\pdffilemoddate{#1}}%
{\pdffilemoddate{#2}}>0%
{\immediate\write18{#3}}\fi%
}
% includesvg[includegraphics args]{file} command (linux-version)
\newcommand{\includesvg}[2][]{%
/usr/bin/inkscape -z -C --file="#2.svg" --export-pdf="#2.pdf" >temp.txt}%
\ifthenelse{\equal{#1}{}}{%
\includegraphics{#2}}{%
\includegraphics[#1]{#2}}%
}


It's directly based on laclaro's "old way" (in German, but the LaTeX is comprehensible combined with my rusty rudiments of German), but with the inkscape options changed.

I'm inclined to suggest this as an option to the really good svg package (with some upgrades to things like the scale specifier, which I may get round to putting in).

Edit: it can now pass arguments to the \includegraphics command

I find the following approach more convenient for my work. My figures are created via Inkscape and Python.

## MWE

\documentclass[]{memoir}
\usepackage{svg}

\begin{document}

\begin{figure}[!ht]
\centering
\includesvg[width=0.5\columnwidth, svgpath = /yourPATHtoSVG/]{filename}
\end{figure}

\end{document}


One can compile MWE above with following command line

pdflatex -synctex=1 -interaction=nonstopmode --shell-escape %.tex

Note: filename is just the name of the figure, without .svg extension.

The svg package is here.

• You need also to have Inkscape installed in your system, and findable in your PATH environment variable. If you encounter some compilation warnings like "PDF inclusion: multiple pdfs with page group included in a single page", you can safely silence them by including the command \pdfsuppresswarningpagegroup=1 after \usepackage{svg}, see this question. – Alessander Botti Benevides Dec 28 '17 at 23:05

All the approaches presented so far rely on an external program creating an intermediate file which is then included as an image. One can actually do this inplace using the Cairo and Rsvg2 libraries via the FFI (Foreign Function Interface) of LuaJITTeX or LuaTeX ≥ 1.0.3. The FFI needs the --shell-escape option.

Is there a way to include SVG diagrams directly without conversion to an intermediate format?

Not to brag but I believe that my answer is the only one actually answering the question.

Below I show how to convert a sample SVG from Wikipedia using this approach. I saved https://en.wikipedia.org/wiki/File:Bitmap_VS_SVG.svg as test.svg in the working directory.

CAVEAT: Calling C code is inherently unsafe. Because C functions are called within the scope of the Lua interpreter, memory faults in the library calls may result in memory corruption which could lead to a segmentation fault, crashing LuaTeX.

\documentclass{article}
\usepackage{luacode}

\begin{luacode}
local ffi = require("ffi")

ffi.cdef[[
// Types
typedef struct FILE_tag FILE;
typedef struct RsvgHandle_tag RsvgHandle;
typedef struct cairo_surface_tag cairo_surface_t;
typedef enum cairo_status_tag cairo_status_t;
typedef struct cairo_tag cairo_t;
typedef int (*cairo_write_func_t)(void *, const unsigned char *, unsigned int);

typedef struct {
int domain;
int code;
char *message;
} GError;

typedef struct {
int width;
int height;
double em;
double ex;
} RsvgDimensionData;

// Conversion functions
RsvgHandle * rsvg_handle_new_from_file(const char *, GError **);
void rsvg_handle_get_dimensions(RsvgHandle *, RsvgDimensionData *);
cairo_surface_t * cairo_pdf_surface_create_for_stream(cairo_write_func_t, FILE *, double, double);
cairo_status_t cairo_surface_status(cairo_surface_t *surface);
cairo_t * cairo_create(cairo_surface_t *);
cairo_status_t cairo_status(cairo_t *cr);
void cairo_scale(cairo_t *, double, double);
int rsvg_handle_render_cairo(RsvgHandle *, cairo_t *);

// Cleanup functions
void cairo_destroy(cairo_t *);
void cairo_surface_destroy(cairo_surface_t *);
void g_object_unref(void *);
]]

local CAIRO_STATUS_SUCCESS = 0

function svg_to_pdf(params, filename)
-- Open input file
local err = ffi.new("GError*[1]", ffi.NULL)
local rsvg = lrsvg.rsvg_handle_new_from_file(filename, err)
if rsvg == ffi.NULL then
tex.error(ffi.string(err[0].message))
end
-- Get size of image
local dimensions = ffi.new("RsvgDimensionData[1]")
lrsvg.rsvg_handle_get_dimensions(rsvg, dimensions)

local width = params.scale * dimensions[0].width
local height = params.scale * dimensions[0].height

-- Open cairo PDF canvas of same size and associate callback function
local output = ""
function rsvg_cairo_write_func(_, data, length)
output = output .. ffi.string(data, length)
return CAIRO_STATUS_SUCCESS
end
local surface = lcairo.cairo_pdf_surface_create_for_stream(
rsvg_cairo_write_func, nil, width, height);
local status = lcairo.cairo_surface_status(surface)
if status ~= CAIRO_STATUS_SUCCESS then
tex.error("Cairo surface error (code " .. status .. ")")
end

-- Render SVG on the canvas
local cr = lcairo.cairo_create(surface)
local status = lcairo.cairo_status(cr)
if status ~= CAIRO_STATUS_SUCCESS then
tex.error("Cairo error (code " .. status .. ")")
end
lcairo.cairo_scale(cr, params.scale, params.scale);
local success = lrsvg.rsvg_handle_render_cairo(rsvg, cr)
if success == 0 then
tex.error("Rsvg rendering failed")
end

-- Clean up
if (cr ~= ffi.NULL) then lcairo.cairo_destroy(cr) end
if (surface ~= ffi.NULL) then lcairo.cairo_surface_destroy(surface) end
if (rsvg ~= ffi.NULL) then lrsvg.g_object_unref(rsvg) end
if (err[0] ~= ffi.NULL) then lrsvg.g_object_unref(err[0]) end

return output
end
\end{luacode}

\newcommand\includesvg[2][scale=1]{%
\leavevmode
\luaexec{
local stream = svg_to_pdf({#1},[[#2]])
local identifier
if status.luatex_version < 108 then
_, identifier = epdf.openMemStream(stream,\#stream,[[#2]])
else
identifier = pdfe.new(stream,\#stream,[[#2]])
end
node.write(img.node { filename = identifier })
}%
}

\begin{document}

\includesvg[scale=.3]{test.svg}

\end{document}


If you are using LyX, then it is simple; add the directory of Inkscape to the "Paths" in LyX's settings, reconfigure twice, and you can include SVG files just like any other files.

If you are writing LaTeX code, maybe the package svg-inkscape will help you. (I never tried)

Although this is a bit of a late answer, I just noticed this question today. For quite some time, I've been using a small package which I wrote to do this (as well as including simple LyX files), which I've called "cludein" -- it works well with POSIX operating-systems, and requires running pdflatex with the -shell-escape flag.

Not sure if I should post it here, but since I don't have it anywhere else on the internet at the moment, why not:

% cludein.sty: Include various file formats directly in a LaTeX file

% *****************************************************************************
% *******   NOTE: pdflatex must be run with the -shell-escape flag in order for
% *******         this package to work.
% *****************************************************************************

% This package provides the following commands:
%    \includesvg -- include an SVG image
%    \svgfig     -- create a Figure environment with an SVG image
%    \includelyx -- include a LyX image
%
% USAGE:
%   \includesvg[width]{path/to/dir/of/svg/file}{name-of-svg-file-without-extension}
%
%   \svgfig[placement][label][width]{figname}{caption-text}
%       -- default arguments can be used with an empty []:
%       for example, \svgfig[tb][][5cm]{myfigname}{Some caption text.}
%       uses the default label of fig:myfigname (in this example).
%
%   \includelyx{path/to/dir/of/lyx/file}{name-of-lyx-file-without-extension}

\NeedsTeXFormat{LaTeX2e}
\RequirePackage[multidot]{grffile} % allow multiple dots in graphics filenames
\RequirePackage{xargs}
\RequirePackage{color}
\RequirePackage{graphicx}

\ProvidesPackage{cludein}[2011/01/17 v0.1
direct inclusion of various file formats]
\typeout{-> cludein.sty <- by Mark Edgington, 2011}
%
%%%%%%%%%%%% BEGIN: auto-include SVG / LyX files %%%%%%%%%%%%%

% usage: \includesvg[width]{path/to/dir/of/svg/file}{name-of-svg-file-without-extension}
% if source file doesn't exist, nothing is done...

\ifnum\pdfstrcmp{\pdffilemoddate{#1}}%
{\pdffilemoddate{#2}}>0%
{\immediate\write18{#3}}\fi%
}

\newcommand{\includesvg}[3][\undefined]{%
\IfFileExists{#2/#3.svg}{%
{mkdir -p #2/output ; %
inkscape -z -D --file=#2/#3.svg %
--export-pdf=#2/output/#3.pdf --export-latex}%
\graphicspath{{#2/output/}}% search here for output pdf
% set figure width
\ifx#1\undefined
\let\svgwidth\undefined
\else
\def\svgwidth{#1}
\fi
% properly center a potentially overwide image
\makebox[\textwidth][c]{%
\input{#2/output/#3.pdf_tex}%
}%
}{\colorbox[rgb]{0.7,0.7,0.7}{\textcolor{black}{MISSING FIGURE}} }% end of IfFileExists
}

\newcommand{\includesvgnobox}[3][\undefined]{%
\IfFileExists{#2/#3.svg}{%
{mkdir -p #2/output ; %
inkscape -z -D --file=#2/#3.svg %
--export-pdf=#2/output/#3.pdf --export-latex}%
\graphicspath{{#2/output/}}% search here for output pdf
% set figure width
\ifx#1\undefined
\let\svgwidth\undefined
\else
\def\svgwidth{#1}
\fi
% properly center a potentially overwide image
\input{#2/output/#3.pdf_tex}%
}{\colorbox[rgb]{0.7,0.7,0.7}{\textcolor{black}{MISSING FIGURE}} }% end of IfFileExists
}

% TODO: make secondary \includesvg command which instead of directly exporting to PDF (which
% currently is uncompressed with inkscape), does something which results in a compressed PDF. (maybe
% postprocess the uncompressed pdf?)

% usage: \svgfig[placement][label][width]{figname}{caption-text}
% -- default arguments can be used with an empty []:
%    for example, \svgfig[tb][][5cm]{myfigname}{Some caption text.}
%    uses the default label of fig:myfigname (in this example).
\newcommandx{\svgfig}[5][1=tb, 2=\undefined, 3=\undefined, usedefault]{%
\begin{figure}[#1]%
\begin{center}%
\includesvg[#3]{svg}{#4}%
\caption{#5}%
\ifx#2\undefined%
\label{fig:#4}%
\else%
\label{#2}%
\fi%
\end{center}%
\end{figure}%
}

% export and include lyx files!
% sed is used to keep only the stuff inside the document-environment
% sed command is: sed -i '0,/\\begin{document}/d; /\\end{document}/,$d' file-to-replace.tex \newcommand{\includelyx}[2][lyx]{% \executeiffilenewer{#1/#2.lyx}{#1/output/#2.lyx_tex}% { mkdir -p #1/output ; % lyx -e pdflatex #1/#2.lyx ; % mv #1/#2.tex #1/output/#2.lyx_tex ; % /bin/sed -i '% 0,/\string\\begin{document}/d; /\string\\end{document}/,$d
' %
#1/output/#2.lyx_tex}
\input{#1/output/#2.lyx_tex}%
}

%%%%%%%%%%%% END: auto-include SVG / LyX files %%%%%%%%%%%%%

• Note, that also the recently published package svg contains a command \includesvg, cf. my answer. Not that you need it with your own approach … – Speravir Sep 30 '12 at 0:53

Another alternative is to use svg2pdf, from the Gnome Librsvg library (which is available on Linux and OSX (via MacPorts/brew)), to convert the SVG file to PDF format and include it as a PDF in Latex. This appears to produce a vector version of the figure which looks good.

Here's an example of how to use it:

svg2pdf mydiagram.svg mydiagram.pdf

• Note that the question explicitly asks for inclusion without conversion to an intermediate format. – Stephan Lehmke Jan 15 '14 at 16:54
• Installing various librsvg2-* packages on Debian Jessie doesn't make svg2pdf available. It does make rsvg-convert available though, which can be used as described here: superuser.com/a/381128/199930 – Ioannis Filippidis Dec 21 '16 at 13:12

If you are in engineering or any of the sciences, I would check out Ngraph also:

http://sourceforge.net/projects/ngraph-gtk/

If you have installed inkscape then you can run the following command that exports your svg image to PDF and LaTeX format.

inkscape -D -z --file=image.svg --export-pdf=image.pdf --export-latex


After that, you can include the image in LaTeX:

\begin{figure}[h]
\centering
\def\svgwidth{\columnwidth}
\input{images/image.pdf_tex}