为什么在 Pgfplots 中配置一个具有用户定义数量的离散颜色并且在颜色之间的边界上精确放置刻度的颜色条如此困难?
考虑这个例子:
\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={%
ymin=\pgfkeysvalueof{/pgfplots/point meta min},
ytick distance={(\pgfkeysvalueof{/pgfplots/point meta max}-\pgfkeysvalueof{/pgfplots/point meta min})/13.0},
% ytick={%
% \pgfkeysvalueof{/pgfplots/point meta min},%
% \pgfmathparse{\pgfkeysvalueof{/pgfplots/point meta min}+(\pgfkeysvalueof{/pgfplots/point meta max}-\pgfkeysvalueof{/pgfplots/point meta min})/13.0}%
% \pgfmathresult,%
% ...,%
% \pgfkeysvalueof{/pgfplots/point meta max}
% }
}
]
\addplot3[surf,shader=interp]
{exp(-x^2-y^2)*x+0.5};
\end{axis}
\end{tikzpicture}
\end{document}
不幸的是,它只产生:
如何强制 Pgfplots 在和的颜色条末端放置刻度\pgfkeysvalueof{/pgfplots/point meta min}
,\pgfkeysvalueof{/pgfplots/point meta max}
并均匀分布剩余的刻度以准确落在颜色过渡上?
我的下一次尝试(参见代码中注释掉的部分)利用ytick={<first>,<second>,...,<last>}
选项并通过\pgfmathparse{...}
计算<second>
刻度,最终导致 TeX 解析错误。
我还能做什么来获得期望的结果?
答案1
使用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}
这需要 pgfplots 1.14(最新稳定版本)。
请注意,该图像 1:1 相当于
\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}
只是这contour filled
允许在选择轮廓位置时有更大的自由度。
答案2
使用以下方式明确设置颜色条刻度
colorbar style={
ytick={<first>,<first>+(<last>-<first>)/<levels>,...,<last>}
}
成功了。
必须根据和<first>,<second>,...,<last>
的值以及所需的颜色数量来计算三个勾选列表元素。/pgfplots/point meta min
/pgfplots/point meta max
<levels>
但是,PGF 提供的数学解析功能\pgfmathparse{...}
和\pgfmathresult
似乎无法用于轴配置中的浮点表达式求值。也不能直接在内部使用\pgfkeysvalueof{/pgfplots/point meta min}
和来设置限制。\pgfkeysvalueof{/pgfplots/point meta max}
ytick={...}
最幸运的是,有 LaTeX3 可扩展数学解析器\fp_eval:n{...}
,它可以轻松地完成刻度计算,并且还用于包装刻度下限和上限。
更新
截至 PGFPlots-1.14,\pgfkeysvalueof{/pgfplots/point meta max}
返回前导字符和尾随字符不属于 fp 数字的值,并导致\fp_eval:n
ytick={...} 内部失败。作为一种解决方法,计算被移至every tick/.append code={...}
。
具有 13 个颜色级别的示例:
当前 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}
以前 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}