Introduction
I want to create a heatmap using TikZ. You can see the basic idea in the picture below: I basically have a table of values and each value is assigned a color. The picture is the result of the R package ggplot2, which however has some limitations. Thus it was my idea to do the heat maps in LaTeX/TikZ.
Sorry if this gets lengthy but I want to describe unambiguously what I want to do.
What I want to plot
- I want to plot a table.
- Each cell should have the same size and a value inside it. The values are signed integers. The raw values are printed centered in the cell. Additionally, I want to give the cells a background color, which basically is
blue!{value * -0.05}
for negative values andred!{value * 0.05}
for positive values. - For the colors, I want replace all negative values < -200 by -200, all positive values > 200 by 200.
- I want to have a horizontal and a vertical axis with labels.
I will probably generate LaTeX and TikZ code using a preprocessing script. However, I hoped that I could plot the cells with macros to make the result more compact.
How far I got on my own
I have done 1-3 on my own - more or less elegantly. My problem is now how to draw the axes in a nice way.
My questions
- Can I improve the current code for 1-3?
- How can I draw the axes elegantly and without having to specify manual coordinates?
Example Data
As requested, here is some example data.
The full data looks as follows. I imported this data into R and then filtered by the values of the dummycol{1,2,3}. I could generate one data file per heat map, however, without problems.
dummycol1 dummycolo2 rowlabel dummycol3 valuecol1 valuecol2 valuecol3 valuecol4
. . 100 . -86 -81 -124 -138
. . 99 . -90 -96 -122 -108
. . 98 . -91 -105 -92 -55
Code
Here is my current code:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning}
\usepackage{ifthen}
\newcommand{\trimmed}{foo}
\newcommand{\bgcolor}{foo}
\newcommand{\hmValue}{0}
\newcommand{\transparency}{0}
\newcommand{\hmColor}{}
\newcommand{\HeatmapNode}[1]{
\ifthenelse{#1 < -200}
{
\renewcommand{\trimmed}{-200}
}
% else
{
\ifthenelse{#1 > 200}
{
\renewcommand{\trimmed}{200}
}
% else
{
\renewcommand{\trimmed}{#1}
}
}
\ifthenelse{#1 < 0}
{
\pgfmathparse{round(\trimmed * -0.5)}
\node [fill=red!\pgfmathresult] {#1};
}
% else
{
\pgfmathparse{round(\trimmed * 0.5)}
\node [fill=blue!\pgfmathresult] {#1};
}
}
\begin{document}
\begin{tikzpicture}
\matrix(A) [nodes={rectangle,minimum width=2cm,minimum height=1cm}]
{
\node {0}; & \HeatmapNode{-300} & \HeatmapNode{-200} & \HeatmapNode{-100} \\
\node {1}; & \HeatmapNode{0} & \HeatmapNode{100} & \HeatmapNode{200} \\
\node {2}; & \HeatmapNode{300} & \HeatmapNode{40} & \HeatmapNode{800} \\
\node {}; & \node{30}; & \node{50}; & \node{70}; \\
};
\end{tikzpicture}
EDIT Adding example data.
\newcommand{\HeatmapNode}[1]{\pgfmathparse{round(min(abs(#1),200) * 0.5)}\node [fill=\ifnum#1>0 blue\else red\fi!\pgfmathresult] {#1};}