1

I have a bunch of figures that contain line plots to which I would like to add a background image showing the geometry compared to the data. What I would like to know is: How can I add a semi-transparent background image to my axes that is in relative coordinates of the axis? In other words, I would like to have the image width be equal to the width of the axes.

Here is the MWE:

\documentclass[class=minimal,border=0pt]{standalone}
\usepackage{graphicx}           % Add graphics
\usepackage{mathpazo}           % Change math and rm fonts to palatino
\usepackage{transparent}        % For changing image opacity
\usepackage{tikz}               % For drawing figures
\usetikzlibrary{calc}           % For making complex coordinate calculations
\usepackage{pgfplots}           % For generating plots
    \pgfplotsset{compat=newest} % Use newest version of pgfplots
\usepackage{mwe}
\usepackage{filecontents}
\begin{filecontents*}{test.data}
Y,U,V,W
130,-3.704216e-02,3.019000e-03,3.200443e-01
170,6.075245e-03,-2.507332e-02,-1.83164e-01
210,6.075245e-03,-2.507332e-02,-1.83164e-01
\end{filecontents*}

\begin{document}
\begin{tikzpicture}
    \pgfplotsset{every axis/.append style={width=2.5in,height=2.5in}}
    \pgfplotsset{every axis/.append style={xmin=129.5,xmax=221,xtick={120,140,160,180,200,220}}}
    \pgfplotsset{every axis legend/.append style={at={(0,1.03)},anchor=south west,nodes=right}}
    \begin{axis}[name=topplot,clip mode=individual,
        axis background/.style={fill=white},
        ymin=-0.6,ymax=0.6,
        tick scale binop=\times,
        minor tick num=4,
        legend columns=1,
        ytick pos=both,
        ylabel={Velocity, [m/s]},
        ytick={-0.5,-0.25,0,0.25,0.5},
        y tick label style={
            /pgf/number format/.cd,
            fixed,
            fixed zerofill,
            precision=2,
            /tikz/.cd}]

        \node[draw=none,anchor=south west,opacity=0.5] at (rel axis cs:0,0) {\includegraphics[width=1.75in]{example-image-a}};          
        \addplot+[blue,solid,mark=o]
            table[x=Y,y=U,col sep=comma] {test.data};
            \addlegendentry{u}
        \addplot+[green,solid,mark=square]
            table[x=Y,y=V,col sep=comma] {test.data};
            \addlegendentry{v}
        \addplot+[red,solid,mark=triangle]
            table[x=Y,y=W,col sep=comma]    {test.data};
            \addlegendentry{w}
    \end{axis}
\end{tikzpicture}
\end{document}

EDIT: Removed the every nth point command from code.

1
  • I should also note that in the actual figure I am compiling with LuaLaTeX because there are so many data points in my lines that I run out of memory.
    – Kyle Jones
    Commented Apr 26, 2016 at 18:42

1 Answer 1

2

Edit:

For an axis of arbitrary width, you can compute the width and store that value as described in this answer. Combining that approach with a new command (which I call \bgimage), you can insert a background image with width equal to the axis width.

In the example below I've duplicated the plot to the right, but made it smaller to show the image scales appropriately. Also, the opacity should be handled by TikZ, so I removed the transparent package.

\documentclass[class=minimal,border=0pt]{standalone}
\usepackage{graphicx}           % Add graphics
\usepackage{mathpazo}           % Change math and rm fonts to palatino
\usepackage{tikz}               % For drawing figures
\usetikzlibrary{calc}           % For making complex coordinate calculations
\usepackage{pgfplots}           % For generating plots
    \pgfplotsset{compat=newest} % Use newest version of pgfplots
\usepackage{mwe}
\usepackage{filecontents}
\begin{filecontents*}{test.data}
Y,U,V,W
130,-3.704216e-02,3.019000e-03,3.200443e-01
170,6.075245e-03,-2.507332e-02,-1.83164e-01
210,6.075245e-03,-2.507332e-02,-1.83164e-01
\end{filecontents*}

\pgfkeys{/tikz/savenumber/.code 2 args={\global\edef#1{#2}}}
\providecommand{\findlen}{%
\path
  let
  \p1 = ($(rel axis cs:0,0)$),
  \p2 = ($(rel axis cs:1,0)$),
  \n1 = {veclen(\x1-\x2,\y1-\y2)}
  in
  coordinate(p1) at (\p1)
  coordinate(p2) at (\p2)
  [savenumber={\n}{\n1}]
  ;
  }
\providecommand{\bgimage}[1]{%
\findlen
        \node[draw=none,anchor=south west,opacity=0.3,inner sep=0] at (rel axis cs:0,0) {\includegraphics[width=\n]{#1}}
}
\begin{document}
\begin{tikzpicture}
    \pgfplotsset{every axis/.append style={width=2.5in,height=2.5in,scale only axis}}
    \pgfplotsset{every axis/.append style={xmin=129.5,xmax=221,xtick={120,140,160,180,200,220}}}
    \pgfplotsset{every axis legend/.append style={at={(0,1.03)},anchor=south west,nodes=right}}
    \begin{axis}[name=topplot,clip mode=individual,
        axis background/.style={fill=white},
        ymin=-0.6,ymax=0.6,
        tick scale binop=\times,
        minor tick num=4,
        legend columns=1,
        ytick pos=both,
        ylabel={Velocity, [m/s]},
        ytick={-0.5,-0.25,0,0.25,0.5},
        y tick label style={
            /pgf/number format/.cd,
            fixed,
            fixed zerofill,
            precision=2,
            /tikz/.cd}]
        \bgimage{example-image-a};
        \addplot+[blue,solid,mark=o]
            table[x=Y,y=U,col sep=comma] {test.data};
            \addlegendentry{u}
        \addplot+[green,solid,mark=square]
            table[x=Y,y=V,col sep=comma] {test.data};
            \addlegendentry{v}
        \addplot+[red,solid,mark=triangle]
            table[x=Y,y=W,col sep=comma]    {test.data};
            \addlegendentry{w}
    \end{axis}
\begin{scope}[xshift=3.2in]
    \begin{axis}[width=2in,height=2in,clip mode=individual,
        axis background/.style={fill=white},
        ymin=-0.6,ymax=0.6,
        tick scale binop=\times,
        minor tick num=4,
        legend columns=1,
        ytick pos=both,
        ylabel={Velocity, [m/s]},
        ytick={-0.5,-0.25,0,0.25,0.5},
        y tick label style={
            /pgf/number format/.cd,
            fixed,
            fixed zerofill,
            precision=2,
            /tikz/.cd}]
        \bgimage{example-image-a};
        \addplot+[blue,solid,mark=o]
            table[x=Y,y=U,col sep=comma] {test.data};
            \addlegendentry{u}
        \addplot+[green,solid,mark=square]
            table[x=Y,y=V,col sep=comma] {test.data};
            \addlegendentry{v}
        \addplot+[red,solid,mark=triangle]
            table[x=Y,y=W,col sep=comma]    {test.data};
            \addlegendentry{w}
    \end{axis}

\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

Original answer

Adding inner sep=0pt to the image node will remove the space between the image and the anchor (in this case, south west and (rel axis cs:0,0)).

In order to make the image and plot widths the same, add scale only axis to tikzset. This will make the axes have the declared width, not the entire plot (including labels, etc.)

\documentclass[class=minimal,border=0pt]{standalone}
\usepackage{graphicx}           % Add graphics
\usepackage{mathpazo}           % Change math and rm fonts to palatino
\usepackage{transparent}        % For changing image opacity
\usepackage{tikz}               % For drawing figures
\usetikzlibrary{calc}           % For making complex coordinate calculations
\usepackage{pgfplots}           % For generating plots
    \pgfplotsset{compat=newest} % Use newest version of pgfplots
\usepackage{mwe}
\usepackage{filecontents}
\begin{filecontents*}{test.data}
Y,U,V,W
130,-3.704216e-02,3.019000e-03,3.200443e-01
170,6.075245e-03,-2.507332e-02,-1.83164e-01
210,6.075245e-03,-2.507332e-02,-1.83164e-01
\end{filecontents*}

\begin{document}
\begin{tikzpicture}
    \pgfplotsset{every axis plot/.append style={each nth point=30}}
    \pgfplotsset{every axis/.append style={width=2.5in,height=2.5in,scale only axis}}
    \pgfplotsset{every axis/.append style={xmin=129.5,xmax=221,xtick={120,140,160,180,200,220}}}
    \pgfplotsset{every axis legend/.append style={at={(0,1.03)},anchor=south west,nodes=right}}
    \begin{axis}[name=topplot,clip mode=individual,
        axis background/.style={fill=white},
        ymin=-0.6,ymax=0.6,
        tick scale binop=\times,
        minor tick num=4,
        legend columns=1,
        ytick pos=both,
        ylabel={Velocity, [m/s]},
        ytick={-0.5,-0.25,0,0.25,0.5},
        y tick label style={
            /pgf/number format/.cd,
            fixed,
            fixed zerofill,
            precision=2,
            /tikz/.cd}]

        \node[draw=none,anchor=south west,opacity=0.5,inner sep=0pt] at (rel axis cs:0,0) {\includegraphics[width=2.5in]{example-image-a}};          
        \addplot+[blue,solid,mark=o]
            table[x=Y,y=U,col sep=comma] {test.data};
            \addlegendentry{u}
        \addplot+[green,solid,mark=square]
            table[x=Y,y=V,col sep=comma] {test.data};
            \addlegendentry{v}
        \addplot+[red,solid,mark=triangle]
            table[x=Y,y=W,col sep=comma]    {test.data};
            \addlegendentry{w}
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

6
  • This does exactly what I would like, however I would like to change my width command in includegraphics to be in relative coordinates to that I don't have to change it for every figure. Is there a way to do that? Also, the transparency doesn't seem to work on my end.
    – Kyle Jones
    Commented Apr 26, 2016 at 18:27
  • @KyleJones So your figures may have different widths, and you don't want to set each figure width independently to match?
    – erik
    Commented Apr 26, 2016 at 18:56
  • Yes that is correct. I think I have the transparency issue fixed now by using \transparent{} before \includegraphics.
    – Kyle Jones
    Commented Apr 26, 2016 at 19:02
  • @KyleJones Then why do you have \pgfplotsset{every axis/.append style={width=2.5in,height=2.5in}}? This will make all your axes the same size, thus straightforward to make the images match.
    – erik
    Commented Apr 26, 2016 at 19:37
  • 1
    @KyleJones Please see my updated answer.
    – erik
    Commented Apr 26, 2016 at 20:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .