# PGFPlots custom colorbar for heatmap

plotting data from a matrix as a heatmap works so far. The z values are percentages from 0% to 150%. The problem is that i can't define the colors properly.

The colorbar should look like this:

[0% - 70% = white to mint to green | 71% - 100% = cyan to blue | 101% - 120% = yellow to orange, 121% - 140% = red to black | 141% and above = black]

At 101% needs to be a clear cut so that you can directly tell that the value z is below or above 100%.

I've tried so many things and have been reading the manual up and down but I can't get it defined the way I want it to be.

Here is my working code, all the testing regarding colorbar has been removed since it always led to errors.

\usepackage{filecontents}
\begin{filecontents*}{org.txt}
x, y, z
1, 0, 95
2, 0, 50
1, 1, 110
2, 1, 150
1, 2, 40
2, 2, 37
\end{filecontents*}

\begin{figure}[hp]
\begin{tikzpicture}
\begin{axis}[
colorbar horizontal,
colorbar style={
xticklabel style={
/pgf/number format/.cd,
fixed,
%title=,
precision=0,
fixed zerofill,
},
},
width=18cm,height=22cm,
minor tick num=1,
enlargelimits=false,
axis on top,
point meta min=0,
point meta max=150,
mesh/cols=88,
mesh/rows=89,
x tick label style={rotate=90, font=\tiny},
xlabel={in\%},
]
\addplot [matrix plot*,point meta=explicit] table [meta=z] {org.txt};
\end{axis}
\end{tikzpicture}
\end{figure}


Here is the outcome of it (with the actual data).

Any suggestions and tips are welcome!

Kind regards

Arno

• Welcome to TeX.SE! Can you show us what you have so far? And please make it a minimal working example. – Troy May 19 '18 at 18:05
• And you can play with meta, e.g. meta=ifthenelse(z<1,z,z+2) if you want to make a jump. But it is hard to say more without a minimal working example. – user121799 May 19 '18 at 18:17
• I've added the relevant code and a picture of the plot. – Arno May 19 '18 at 19:42
• Your example is not a MWE and if I add documentclass and pgfplots as a package, then I get some errors. Can you please provide a working example? – TobiBS May 19 '18 at 20:31
• Your statements mesh/cols=88, mesh/rows=89, are at odds with the fact that the table has just 6 rows. IMHO there is no way that the above table can yield something like the picture you are showing. – user121799 May 20 '18 at 0:04

Simple color maps, like the one you want, are straight forward. Just give the color for a position in the form color model(position)=(argument). With the color model color argument is the color name and you can also use definitions like green!50.

Two remarks:

In order to ensure, that the range from 141 to 150 is black, you have to give a color for position 150.

There are visible transition from green to cyan (positions 70 and 71), blue to yellow (100 and 101) and orange to red (120 and 121). If you don't want this, you can write for example 70.01 instead of 71.

Oh, and I replaced the color mint with lime, because mint is not defined.

The result:

Edit:

I added some code to draw things on the colorbar. Note, that with xticklabel cs: the x-coordinates are normalized, i.e. 0 is on the left of the colorbar and 1 on the right. Also, clip=false is necessary to draw outside the plot area.

The colorbar with an arrow:

The code:

\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\usepackage{filecontents}
\begin{filecontents*}{org.txt}
x, y, z
1, 0, 95
2, 0, 50
1, 1, 110
2, 1, 150
1, 2, 40
2, 2, 37
\end{filecontents*}

\pgfplotsset{compat=1.15,
colormap={mycolormap}{
color(0)=(white) color(35)=(lime) color(70)=(green)
color(71)=(cyan) color(100)=(blue)
color(101)=(yellow) color(120)=(orange)
color(121)=(red) color(140)=(black)
color(150)=(black)
}
}

% initial definition
%    colorbar/draw/.code={
%        \axis [every colorbar,colorbar shift,colorbar=false]
%        \endaxis
%    },

% drawing something on a colorbar
\pgfplotsset{
colorbar/draw/.code={
\axis [every colorbar,colorbar shift,colorbar=false,clip=false]
\draw[red,->] (xticklabel cs:0.98,-0.5*\pgfkeysvalueof{/pgfplots/colorbar/width}) --
(xticklabel cs:1.02,-0.5*\pgfkeysvalueof{/pgfplots/colorbar/width});
\endaxis
},
}

\begin{document}
%\begin{figure}[hp]
\begin{tikzpicture}
\begin{axis}[
colormap name=mycolormap,
colorbar horizontal,
colorbar style={
xticklabel style={
/pgf/number format/.cd,
fixed,
%title=,
precision=0,
fixed zerofill,
},
},
width=18cm,height=22cm,
minor tick num=1,
enlargelimits=false,
axis on top,
point meta min=0,
point meta max=150,
mesh/cols=2,
mesh/rows=3,
x tick label style={rotate=90, font=\tiny},
xlabel={in\%},
]