我正在尝试生成一种热图。我有一组区域(矩形),每个区域都有给定的密度。我现在想根据预定义的热图为这些区域着色,也许还添加图例。目前我只是画矩形而不添加颜色,只是在矩形内写入值。
\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}
\draw [fill=black!15,opacity=.5] (2,11) rectangle (6,7);
\draw node at (4,9) {(91.4)};
\draw [fill=black!25,opacity=.5] (2,7) rectangle (6,2);
\draw node at (4,5) {(44.6)};
\draw [fill=black!35,opacity=.5] (6,11) rectangle (10,9);
\draw node at (8,10) {(87.3)};
\end{tikzpicture}
\end{document}
但我更喜欢这样的可视化,这意味着获取矩形的值并根据类似的东西计算热量: 渐变热色
由于这只是一个小例子,从包含所有信息的表格中生成数据也会很有趣。下面是 excel tex 示例表。我通常在 excel 中有数据。但将数据复制粘贴到 tex 文件中对我来说仍然是一个很好的解决方案。
区域 X1 Y1 X2 Y2 值 1 2 11 6 7 91.4 2 2 7 6 2 44.6 3 6 11 10 9 87.3
有人知道吗?我发现的所有示例大多都是对普通表格进行着色,而不是对不同大小的矩形进行着色。这是我对表格所指的:热图示例
答案1
这里有两个版本:一个用于间隔并因此跳跃,另一个用于平滑的颜色过渡。您可以使用\getincolor
和\getoutcolor
宏来定义颜色应循环使用的颜色。对于,\ColorSteps
您需要指定与\ColSteps
所述一样多的颜色,因为\ColorGradients
您需要比\ColIntervals
所述多指定一种,因为颜色是间隔边缘的颜色。为了说明差异,两个图像都包含 100 个区域,值从 0 到 99。由于命令需要知道相对于它们应该缩放的值,因此您需要提供\MinVal
和\MaxVal
,即可能出现的最小值和最大值。
代码
\documentclass[tikz, border=2mm]{standalone}
\newcommand{\ColorSteps}[4][black]%
% [draw color], sw, ne, value
{ \pgfmathsetmacro{\IW}{(\MaxVal-\MinVal)/\ColSteps}
\pgfmathsetmacro{\IN}{div(#4-\MinVal,\IW)}
\shade[inner color=\getincolor{\IN}, outer color=\getoutcolor{\IN}, draw=#1] (#2) rectangle (#3);
}
\newcommand{\ColorGradients}[4][black]%
% [draw color], sw, ne, value
{ \pgfmathsetmacro{\IW}{(\MaxVal-\MinVal)/\ColIntervals}% interval width
\pgfmathsetmacro{\IN}{div(#4-\MinVal,\IW)}% interval number
\pgfmathsetmacro{\NIN}{\IN+1}% next interval number
\pgfmathsetmacro{\IP}{mod(#4-\MinVal,\IW)/\IW*100}% interval percentage
\colorlet{InColorA}{\getincolor{\IN}}
\colorlet{InColorB}{\getincolor{\NIN}}
\colorlet{OutColorA}{\getoutcolor{\IN}}
\colorlet{OutColorB}{\getoutcolor{\NIN}}
\shade[inner color=InColorB!\IP!InColorA, outer color=OutColorB!\IP!OutColorA, draw=#1] (#2) rectangle (#3);
}
\newcommand{\getincolor}[1]%
{\ifcase#1 black% color 0
\or blue% color 1
\or cyan% ...
\or green%
\or yellow%
\or red%
\or violet%
\or white% color 7
\else gray% any number > 7
\fi
}
\newcommand{\getoutcolor}[1]%
{\ifcase#1 black!30!white%
\or blue!30!white%
\or cyan!30!white%
\or green!30!gray%
\or yellow!30!gray%
\or red!30!gray%
\or violet!30!gray%
\or white!30!gray%
\else gray%
\fi
}
\begin{document}
\pgfmathsetmacro{\MinVal}{0}
\pgfmathsetmacro{\MaxVal}{100}
\pgfmathsetmacro{\ColSteps}{8}
\begin{tikzpicture}
\foreach \x in {0,...,9}
{ \foreach \y in {0,...,9}
{ \ColorSteps{\x,\y}{\x+1,\y+1}{10*\y+\x}
}
}
\end{tikzpicture}
\pgfmathsetmacro{\ColIntervals}{7}
\begin{tikzpicture}
\foreach \x in {0,...,9}
{ \foreach \y in {0,...,9}
{ \ColorGradients{\x,\y}{\x+1,\y+1}{10*\y+\x}
}
}
\end{tikzpicture}
\end{document}
输出
答案2
这是汤姆·邦巴迪尔的回答它演示了如何将另一个文件中的值与问题中指定的格式合并。您需要删除标题行,这样您就只剩下值了。
补充的只是这些
\usepackage{textmerg}
这个包将为我们合并数据。
\tikzset{%
make zone/.code args={#1 #2 #3 #4 #5 #6}{%
\ColorGradients{#2,#3}{#4,#5}{#6}
},
}
make zone
是一种 TikZ 样式,它将把值行转换为所需的矩形。它只是 的包装器\ColorGradients
。
我们在数据文件中定义字段。每行都是一个字段,因此每个矩形都有一个字段,其中包含六个值。我们将使用\zone
该字段。
\Fields{\zone}
\makezone
接受一个参数(值的行)并应用make zone
样式。
\newcommand*\makezone[1]{%
\tikzset{make zone={#1}}}
开始上图。
\begin{tikzpicture}
现在我们从文件中合并数据。我们假设如果文件.tex
名为<filename>.tex
,则数据文件名为<filename>.dat
。
\Merge{\jobname.dat}{
现在我们实际创建区域本身。第二个参数中的所有内容都将针对第一个参数中指定的数据文件中的\Merge
每个文件完成。由于我们的数据文件有 3 条线,因此我们应该得到 3 个矩形。\zone
\expandafter\makezone\expandafter{\zone}
关闭合并。
}
\end{tikzpicture}
我们确实得到了 3:
完整代码(主要是 Tom Bombadil 的):
\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{textmerg}
% colour coding is all from Tom Bombadil's answer at https://tex.stackexchange.com/a/283270/
\newcommand{\ColorSteps}[4][black]%
% [draw color], sw, ne, value
{ \pgfmathsetmacro{\IW}{(\MaxVal-\MinVal)/\ColSteps}
\pgfmathsetmacro{\IN}{div(#4-\MinVal,\IW)}
\shade[inner color=\getincolor{\IN}, outer color=\getoutcolor{\IN}, draw=#1] (#2) rectangle (#3);
}
\newcommand{\ColorGradients}[4][black]%
% [draw color], sw, ne, value
{ \pgfmathsetmacro{\IW}{(\MaxVal-\MinVal)/\ColIntervals}% interval width
\pgfmathsetmacro{\IN}{div(#4-\MinVal,\IW)}% interval number
\pgfmathsetmacro{\NIN}{\IN+1}% next interval number
\pgfmathsetmacro{\IP}{mod(#4-\MinVal,\IW)/\IW*100}% interval percentage
\colorlet{InColorA}{\getincolor{\IN}}
\colorlet{InColorB}{\getincolor{\NIN}}
\colorlet{OutColorA}{\getoutcolor{\IN}}
\colorlet{OutColorB}{\getoutcolor{\NIN}}
\shade[inner color=InColorB!\IP!InColorA, outer color=OutColorB!\IP!OutColorA, draw=#1] (#2) rectangle (#3);
}
\newcommand{\getincolor}[1]%
{\ifcase#1 black% color 0
\or blue% color 1
\or cyan% ...
\or green%
\or yellow%
\or red%
\or violet%
\or white% color 7
\else gray% any number > 7
\fi
}
\newcommand{\getoutcolor}[1]%
{\ifcase#1 black!30!white%
\or blue!30!white%
\or cyan!30!white%
\or green!30!gray%
\or yellow!30!gray%
\or red!30!gray%
\or violet!30!gray%
\or white!30!gray%
\else gray%
\fi
}
\begin{document}
\pgfmathsetmacro{\MinVal}{0}
\pgfmathsetmacro{\MaxVal}{100}
\pgfmathsetmacro{\ColIntervals}{7}
\tikzset{%
make zone/.code args={#1 #2 #3 #4 #5 #6}{%
\ColorGradients{#2,#3}{#4,#5}{#6}
},
}
\Fields{\zone}
\newcommand*\makezone[1]{%
\tikzset{make zone={#1}}}
\begin{tikzpicture}
\Merge{\jobname.dat}{
\expandafter\makezone\expandafter{\zone}
}
\end{tikzpicture}
\end{document}