[Tex/LaTex] How to export tikzpictures to png (Using GraphicsMagick?)

exportpngtikz-pgf

I want to export some of my LaTeX figures to .png with a clear background, so I can use them in my PowerPoint presentation. I'm using TexStudio with MikTex on Windows 10. I've been recommended GraphicsMagick by @Harald Hanche-Olsen, but neither of us know how it works in windows.

How do I convert my LaTeX figures (output in PDF) into .png with clear background?

Example figure:

\PassOptionsToPackage{table,dvipsnames,svgnames}{xcolor}
\documentclass[11pt, twoside, a4paper]{report}
\usepackage[inner = 30mm, outer = 20mm,  top = 30mm, bottom = 20mm, headheight = 13.6pt]{geometry}
\usepackage{tikz}
\usepackage[pdfpagelayout=TwoPageRight]{hyperref}
\usepackage[export]{adjustbox}
%\usepackage{showframe}
\hypersetup{colorlinks=true, linktoc=all, allcolors=green!30!black,}

\usepackage{pgfplots}
\pgfplotsset{
    compat=1.16,
    %made the beginnings of a second axis style, because I figured it needs to be different for grouped
    my second axis style/.style={
    width=\linewidth,
    height=0.35\linewidth,
    bar width=0.2, %<- changed
    enlarge x limits={abs=0.45},    % <-- changed to absolute coordinates
    ymin=0,
    legend style={
        at={(0.5,1.15)},    % <-- adapted
        anchor=north,       % <-- changed from `north'
        legend columns=3,
    },
    ylabel={PR\textsubscript{A}},
    xtick=data,
    axis lines*=left,
    ymajorgrids,
    %
    table/x=x,
    },
    % created a style for the common `ybar' options
    my second ybar style/.style={
        ybar,
        my ybar legend,            % <-- change legend image accordingly
        #1!50!black,
        fill=white!70!black,, %<- changed back
        nodes near coords,      % <-- moved from `axis' options here
        % state absolute positions for the `nodes near coords'
        scatter/position=absolute,
        node near coords style={
            % state where the nodes should appear
            at={(\pgfkeysvalueof{/data point/x},0.5*\pgfkeysvalueof{/data point/y})},
            anchor=center,rotate=90, %<-added
            % make the font a bit smaller
            font=\footnotesize,
            /pgf/number format/.cd,
            fixed,
            precision=2,
            zerofill,
        },
    },
    my ybar legend/.style={
        /pgfplots/legend image code/.code={
            \draw [
            ##1,
            /tikz/.cd,
            yshift=-0.25em,
            ] (0cm,0cm) rectangle (3pt,0.8em);
        },
    },
}



%data for the grouped bar chart
\pgfplotstableread{
    x          SP_cSi_2_3   SP_cSi_2_4  Reference
    1   0.500   0.627   0.868
    2   0.781   0.778   0.859
    3   0.819   0.868   0.871
    4   0.732   0.824   0.876
    5   0.853   0.873   0.954
    6    0.813   0.838   0.940
    7    0.712   0.759   0.876
    8    0.864   0.894   0.887
    9    0.465   0.614   0.891
}{\loadedtablesppr}


\begin{document}

    \begin{figure}
        \begin{tikzpicture}
        \begin{axis}[my second axis style,
        ybar,
        ylabel={PR\textsubscript{A}},
        xtick= data,
        ]
        \addplot [my second ybar style=blue!50!black,] table [y=SP_cSi_2_3] {\loadedtablesppr};
        \addplot [my second ybar style=orange!50!black,] table [y=SP_cSi_2_4] {\loadedtablesppr};
        \addplot [my second ybar style=red!50!black,] table [y=Reference] {\loadedtablesppr};
        \legend{Floating 2.3~~ , Floating 2.4~~ , Reference}
        \end{axis}
        \end{tikzpicture}
    \end{figure}

\end{document}

Is there a command like
\savefig{'my_export_image.png', clear = True}?

Best Answer

If you have a lot of plots, it might be cumbersome to make standalone files for all plots. An alternative is to use the external library from either Tikz or pgfplots (the latter is generally more up-to-date according to the documentation).

\usepgfplotslibrary{external}

The following will turn on externalizing, prefix all generated graphics with tikz_external/ in the current directory, and externalize only the tikzpictures that have been named with \tikzsetnextfilename{<name>}.

\tikzexternalize[
    prefix={tikz_external/},
    only named,
]

Note that if the subfolder tikz_external does not exist in the current directory, it might be needed to create this manually. I did not have to do this (also on Windows), but as @knut reported in the comments, this is not standard Windows behavior apparently.

Alternatively you can add the following line to your preamble that creates the directory if it does not exist.

\immediate\write18{if not exist tikz_external mkdir tikz_external}

Then we define a new style which adds a line to the command that Tikz uses to compile your externalized graphics. If you are on Ubuntu or one of its friends, you might want to replace the && with ;.

% Make the 'export as png' a seperate style, with default density 200
\tikzset{
    export as png/.style={
        external/system call/.add={}{
            && convert -density #1 -transparent white "\image.pdf" "\image.png"
        },
    },
    export as png/.default={200},
}

Then by calling the following commands inside your figure, the next tikzpicture will be externalized, and inside the current scope, every externalized figure will also be converted to a .png file.

\tikzset{export as png=<optional density>}
\tikzsetnextfilename{my_externalized_plot}

Then you can compile the whole document with the --shell-escape option enabled, and voila, you files are available as .pngs.

Complete MWE:

\PassOptionsToPackage{table,dvipsnames,svgnames}{xcolor}
\documentclass[11pt, twoside, a4paper]{report}
\usepackage[inner = 30mm, outer = 20mm,  top = 30mm, bottom = 20mm, headheight = 13.6pt]{geometry}
\usepackage{tikz}
\usepackage[pdfpagelayout=TwoPageRight]{hyperref}
\usepackage[export]{adjustbox}
%\usepackage{showframe}
\hypersetup{colorlinks=true, linktoc=all, allcolors=green!30!black,}

\usepackage{pgfplots}
\pgfplotsset{
    compat=1.16,
    %made the beginnings of a second axis style, because I figured it needs to be different for grouped
    my second axis style/.style={
    width=\linewidth,
    height=0.35\linewidth,
    bar width=0.2, %<- changed
    enlarge x limits={abs=0.45},    % <-- changed to absolute coordinates
    ymin=0,
    legend style={
        at={(0.5,1.15)},    % <-- adapted
        anchor=north,       % <-- changed from `north'
        legend columns=3,
    },
    ylabel={PR\textsubscript{A}},
    xtick=data,
    axis lines*=left,
    ymajorgrids,
    %
    table/x=x,
    },
    % created a style for the common `ybar' options
    my second ybar style/.style={
        ybar,
        my ybar legend,            % <-- change legend image accordingly
        #1!50!black,
        fill=white!70!black,, %<- changed back
        nodes near coords,      % <-- moved from `axis' options here
        % state absolute positions for the `nodes near coords'
        scatter/position=absolute,
        node near coords style={
            % state where the nodes should appear
            at={(\pgfkeysvalueof{/data point/x},0.5*\pgfkeysvalueof{/data point/y})},
            anchor=center,rotate=90, %<-added
            % make the font a bit smaller
            font=\footnotesize,
            /pgf/number format/.cd,
            fixed,
            precision=2,
            zerofill,
        },
    },
    my ybar legend/.style={
        /pgfplots/legend image code/.code={
            \draw [
            ##1,
            /tikz/.cd,
            yshift=-0.25em,
            ] (0cm,0cm) rectangle (3pt,0.8em);
        },
    },
}

\immediate\write18{if not exist tikz_external mkdir tikz_external} % Only tested on Windows

\usepgfplotslibrary{external}
\tikzexternalize[
    prefix={tikz_external/},
    only named,
]

%\pgfkeys{/pgf/images/include external/.code=\includegraphics{#1}}

% Make the 'export as png' a seperate style, with default density 200
\tikzset{
    export as png/.style={
        external/system call/.add={}{
            && convert -density #1 -transparent white "\image.pdf" "\image.png"
        },
    },
    export as png/.default={200},
}

%data for the grouped bar chart
\pgfplotstableread{
    x          SP_cSi_2_3   SP_cSi_2_4  Reference
    1   0.500   0.627   0.868
    2   0.781   0.778   0.859
    3   0.819   0.868   0.871
    4   0.732   0.824   0.876
    5   0.853   0.873   0.954
    6    0.813   0.838   0.940
    7    0.712   0.759   0.876
    8    0.864   0.894   0.887
    9    0.465   0.614   0.891
}{\loadedtablesppr}


\begin{document}

    \begin{figure}
        \tikzset{export as png}
        \tikzsetnextfilename{my_externalized_plot}
        \begin{tikzpicture}
        \begin{axis}[my second axis style,
        ybar,
        ylabel={PR\textsubscript{A}},
        xtick= data,
        ]
        \addplot [my second ybar style=blue!50!black,] table [y=SP_cSi_2_3] {\loadedtablesppr};
        \addplot [my second ybar style=orange!50!black,] table [y=SP_cSi_2_4] {\loadedtablesppr};
        \addplot [my second ybar style=red!50!black,] table [y=Reference] {\loadedtablesppr};
        \legend{Floating 2.3~~ , Floating 2.4~~ , Reference}
        \end{axis}
        \end{tikzpicture}
    \end{figure}

\end{document}

Note that I use ImageMagick. I am unsure whether this also works with GraphicsMagick, but the idea would stay the same. Only the external/system call/.add key would be slightly different probably. Additionally, GhostScript is needed for ImageMagick to read PDF files.