colorbar with definite number of discrete colours; with matching ticks placement

Explicit setting of the colour bar ticks using

colorbar style={
  ytick={<first>,<first>+(<last>-<first>)/<levels>,...,<last>}
}

does the trick.

The three ticklist elements <first>,<second>,...,<last> must be calulated based on the values of /pgfplots/point meta min and /pgfplots/point meta max and the desired number of colour <levels> .

However, the PGF-provided math parsing facilities \pgfmathparse{...} and \pgfmathresult seem to be unusable for the evaluation of floating point expressions in the axis configuration. Nor may \pgfkeysvalueof{/pgfplots/point meta min} and \pgfkeysvalueof{/pgfplots/point meta max} be directly used inside ytick={...} to set the limits.

Most fortunately, there is the LaTeX3 expandable math parser \fp_eval:n{...} which graciously accomplishes the tick calculation and which is also used to wrap the lower and upper tick limits.

UPDATE

As of PGFPlots-1.14, \pgfkeysvalueof{/pgfplots/point meta max} returns values with leading and trailing characters which do not belong to the fp numbers and cause \fp_eval:n to fail inside ytick={...}. As a workaround the calculations are moved into every tick/.append code={...}.

Example with 13 colour levels:

enter image description here

Code for current PGFPlots-1.14:

\documentclass[tikz,border=3pt]{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.14}

\usepackage{expl3}
\ExplSyntaxOn
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \fpEval{<expression>}
% expandably evaluate floating point <expression>
\let\fpEval\fp_eval:n
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
\begin{axis}[
  domain=-2:2,
  view={0}{90},
  colormap={CM}{
  samples of colormap=(13 of hot)},
  colormap access=piecewise constant,
  colorbar right,
  colorbar style={%
     ytick={%
       \aval,\bval,...,\cval%
%       \fpEval{\pgfkeysvalueof{/pgfplots/point meta min}},%
%       \fpEval{\pgfkeysvalueof{/pgfplots/point meta min}+(\pgfkeysvalueof{/pgfplots/point meta max}-\pgfkeysvalueof{/pgfplots/point meta min})/13},
%       ...,
%       \fpEval{2*\pgfkeysvalueof{/pgfplots/point meta max}}
     },
     every tick/.append code={%
       \xdef\aval{\fpEval{\pgfkeysvalueof{/pgfplots/point meta min}}}
       \xdef\bval{\fpEval{\pgfkeysvalueof{/pgfplots/point meta min}+(\pgfkeysvalueof{/pgfplots/point meta max}-\pgfkeysvalueof{/pgfplots/point meta min})/13}}
       \xdef\cval{\fpEval{2*\pgfkeysvalueof{/pgfplots/point meta max}}}
     }
  },
]
\addplot3[surf,shader=interp]
{exp(-x^2-y^2)*x};
\end{axis}
\end{tikzpicture}
\end{document}

Code for previous PGFPlots-1.13:

\documentclass[tikz,border=3pt]{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.13}

\usepackage{expl3}
\ExplSyntaxOn
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \fpEval{<expression>}
% expandably evaluate floating point <expression>
\let\fpEval\fp_eval:n
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
\begin{axis}[
  domain=-2:2,
  view={0}{90},
  colormap={CM}{
  samples of colormap=(13 of hot)},
  colormap access=piecewise constant,
  colorbar right,
  colorbar style={%
     ytick={%
       \fpEval{\pgfkeysvalueof{/pgfplots/point meta min}},%
       \fpEval{\pgfkeysvalueof{/pgfplots/point meta min}+(\pgfkeysvalueof{/pgfplots/point meta max}-\pgfkeysvalueof{/pgfplots/point meta min})/13},%
       ...,%
       \fpEval{\pgfkeysvalueof{/pgfplots/point meta max}*2} %increase limit to ensure placement of uppermost tick label
     }
  }
]
\addplot3[surf,shader=interp]
{exp(-x^2-y^2)*x};
\end{axis}
\end{tikzpicture}
\end{document}

Use ytick=data:

\documentclass[tikz,border=3pt]{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.13}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
  domain=-2:2,
  view={0}{90},
  colormap={CM}{
  samples of colormap=(13 of hot)},
  colormap access=piecewise constant,
  colorbar right,
  colorbar style={%
     ytick=data,
  }  
]
\addplot3[surf,shader=interp]
{exp(-x^2-y^2)*x+0.5};
\end{axis}
\end{tikzpicture}
\end{document}

This requires pgfplots 1.14 (the most recent stable).

enter image description here

Note that the image is 1:1 equivalent to

\documentclass[tikz,border=3pt]{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.13}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
  domain=-2:2,
  view={0}{90},
  colorbar right,
  colorbar style={%
     ytick=data,
  }  
]
\addplot3[contour filled={number=13}]
{exp(-x^2-y^2)*x+0.5};
\end{axis}
\end{tikzpicture}
\end{document}

except that contour filled allows somewhat more freedom to choose the contour positions.

Tags:

Pgfplots