Highlighting in TikZ plots

Elaborating plotted data and drawing conclusions from them in a (scientific) report can be cumbersome and often takes way too many words than necessary. Following the old saying ‘a picture is worth a thousand words‘, this post describes how to highlight certain areas in a TikZ plot. You’ll be able to adjust the color of the highlighted area, its layer depth and range. I find this to be a very elegant and clear way of elaborating plots in reports.


The idea of this post came from this question on TeX.SE, and part of the solution is obtained using this answer on TeX.SE.

What you’ll be creating

The example

The example we will be working on will be as simple as possible; a sine function:

highlighttikz nohighlight Highlighting in TikZ plots

The image is created with the following code:

\documentclass{article}
 
% load the required package(s)
\usepackage{pgfplots}
\pgfplotsset{compat=newest} % necessary for new features
 
% begin document
\begin{document}
% create a TikZ picture
\begin{tikzpicture}
\begin{axis}[
    set layers,
    domain=0:10,
    grid=both
]
\addplot+[no marks] {sin(deg(x))};
 
\end{axis}
\end{tikzpicture}
% close document
\end{document}

This piece of code won’t be explained any further. It is just a very minimal document that plots a sine function (sin(x), x=1:10) using TikZ.

Highlighting

In order to give a thorough illustration, I’ll highlight three areas in the sine plot that was described above. The choice for multiple highlighted areas is done in order to illustrate some of the functions you can play with. See the highlighted plot below:

highlighttikz Highlighting in TikZ plots

This TikZ image is created with the following lines of code:

\documentclass{article}
 
% load the required package(s)
\usepackage{pgfplots}
\pgfplotsset{compat=newest} % necessary for new features
 
% code to enable highlighting
\pgfkeys{%
  /tikz/on layer/.code={
    \pgfonlayer{#1}\begingroup
    \aftergroup\endpgfonlayer
    \aftergroup\endgroup
  }
}
 
\pgfplotsset{
    highlight/.code args={#1:#2}{
        \fill [every highlight] ({axis cs:#1,0}|-{rel axis cs:0,0}) rectangle ({axis cs:#2,0}|-{rel axis cs:0,1});
    },
    /tikz/every highlight/.style={
        on layer=\pgfkeysvalueof{/pgfplots/highlight layer},
        blue!20	% default color of highlighted area
    },
    /tikz/highlight style/.style={
        /tikz/every highlight/.append style=#1
    },
    highlight layer/.initial=axis background	% default depth
}
% end code to enable highlighting
 
% begin document
\begin{document}
% create a TikZ picture
\begin{tikzpicture}
\begin{axis}[
    set layers,
    domain=0:10,
    grid=both
]
\addplot+[%
	no marks,
	% first highlighted area (in blue by default) 
	highlight=0:2, 				% range
	% second highlighted area (color changed to red) 	
	highlight style={red!20},	% color
	highlight layer=axis ticks,	% depth
	highlight=6:8,				% range
	% first highlighted area (color changed to green) 	
	highlight style={green!20},	% color
	highlight layer=axis foreground,	% depth
	highlight=7:7.5				% range	
	] 
	{sin(deg(x))};
\end{axis}
\end{tikzpicture}
% close document
\end{document}

Now, the important parts of this code are commented but nonetheless I’ll be discussing the color, layer depth and range a bit more.

Color

Color of the highlighted area is blue!20 by default, as defined in the preamble of the document. When having multiple highlighted areas, you might want to give each area a different color. To do this, specify highlight style={...} within the tikzpicture environment (as an argument of addplot+).
In the example above I’ve highlighted three areas: one with the default color (blue!20) and two of a different color (red!20 and green!20).

Layer depth

The layer depth is the layer on wich the highlight is printed. In most cases, it is best to add a layer in the very background (this is also set by default). Change the layer depth with highlight layer=..., default value is ‘axis background’. The sequence is layer depth is:
axis background, main, axis grid, axis ticks, axis lines, axis tick labels, axis descriptions, axis foreground.
The three highlighted areas in the example above illustrate the effect of the layer depth. The green area’s depth is set to axis ticks and it can be seen that that area is printed on top of the grid (which is the deepest layer). The red area is printed on the very top layer.

Range

Determine the range of the highlighted area by specifying highlight=.... Note that this one is necessary to actually print the area (the color and layer depth described above are not). All options concerning color/style and layer depth should be specified before this command.

3 Comments

  1. Somename says:

    The highlighting does not work well with \addlegendentry.

    Here is my example:

    \begin{tikzpicture}
    \begin{axis}[
    set layers,
    xmode=linear,
    ymode=linear,
    axis x line*=bottom,
    axis y line*=left,
    tick label style={font=\small},
    grid=both,
    tick align=outside,
    tickpos=left,
    xlabel=Batch Identifiers,
    ylabel=$a^s_{i,k}$ (in milliseconds),
    xmin=1790, xmax=1849,
    ymin=-6, ymax=8,
    width=0.45\textwidth,
    height=0.4\textwidth,
    ]
    \def\datapath{‘/Users/junliu/MyFolder/plots-data/One-Way-Delays/Results—1-Mixed-CP-PBT-2conn-ConnSet1-noDAC-Tspec1-origM-D20-origTB—2-Mixed-CP-PBT-2conn-ConnSet1-noDAC-Tspec1-origM-D20-origTB/intermediate_data’};
    \addplot [raw gnuplot, color=red] gnuplot {
    set loadpath \datapath;
    plot “data file” using 1:3 w lines;
    };
    \addlegendentry{z1}
    \addplot [raw gnuplot, color=blue] gnuplot {
    set loadpath \datapath;
    plot “data file” every using 1:4 w lines;
    };
    \addlegendentry{z2}
    \addplot+[%
    no marks, raw gnuplot, color=green,
    % first highlighted area (in blue by default)
    highlight=1822:1839, % range
    % second highlighted area
    highlight=1845:1848, % range
    % third highlighted area
    highlight=53:61 % range
    ] gnuplot {
    set loadpath \datapath;
    plot “data file” using 1:5 w lines;
    };
    \addlegendentry{z3}
    \addplot+[%
    no marks, raw gnuplot, color=yellow,
    highlight style={red!20}, % color
    % first highlighted area
    highlight=1797:1800, % range
    % second highlighted area
    highlight=1804:1814, % range
    % third highlighted area
    highlight=1816:1820, % range
    % fourth highlighted area
    highlight=1843:1846 % range
    ] gnuplot {
    set loadpath \datapath;
    plot “data file” using 1:6;
    };
    \addlegendentry{z4}
    \end{axis}
    \end{tikzpicture}

    Whenever, the highlight is used in \addplot, the legend becomes a large box which covers the main data plot. Do you have a suggestion to deal with this case? Thank you.

  2. percusse says:

    Hi there,

    Great blog! One nitpick; compat=newest is not always the best practice since a newer version can break the functionality of the code. Instead, using the version number that the code is created with, e.g., compat=1.8 should make things smoother for debugging.

Leave a Reply




XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>