我遇到的问题是,在下面的图中,A 的坐标文本附近的右节点丢失了。问题的根源是数据中的舍入误差:它们的总和应该为 100,但在 A 中却多了一些。避免这种情况的最佳方法是什么?简单地将 A 向下舍入不是一个选择。我有大量这样的图,有更多列,几乎每个图中都有一行的总和有点太大。
\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}
\pgfplotsset{
my stackbar plot/.style={
xbar stacked,
xmin=0,xmax=100,
symbolic y coords={A,B},
ytick=data,
nodes near coords={xxx},}}
\begin{document}
\begin{tikzpicture}
\pgfplotstableread[col sep=space]{
text -- -
B 50 50
A 50.01 50
}\data
\begin{axis}[my stackbar plot,]
\addplot table [x expr = \thisrow{--},y=text] {\data};
\addplot table [x expr = \thisrow{-}, y=text] {\data};
\end{axis}
\end{tikzpicture}
\end{document}
答案1
我认为最明智的解决方案是将这些值标准化。下面是我最后使用的代码的简化版本:
\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}
\pgfplotsset{
my stackbar plot/.style={
xbar stacked,
xmin=0,xmax=100,
symbolic y coords={A,B},
ytick=data,
nodes near coords={xxx},}}
\begin{document}
\begin{tikzpicture}
\pgfplotstableread[col sep=space]{
text -- -
B 50 50
A 50.01 50
}\data
\pgfplotstablecreatecol[create col/expr={\thisrow{--}+\thisrow{-}}]{sum}\data
\pgfplotstablecreatecol[create col/expr={\thisrow{--}/\thisrow{sum}*100}]{--}\data
\pgfplotstablecreatecol[create col/expr={\thisrow{-}/\thisrow{sum}*100}]{-}\data
\begin{axis}[my stackbar plot,]
\addplot table [x expr = \thisrow{--},y=text] {\data};
\addplot table [x expr = \thisrow{-}, y=text] {\data};
\end{axis}
\end{tikzpicture}
\end{document}
编辑
进一步的测试表明,标准化是不够的。总数仍然可能比 100 大一点,因此标记可能会丢失。有必要截断这些值,请参阅pgfplots:纠正舍入问题。
答案2
还可以仅对加起来不等于 100 的行中的值进行规范化:
\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}
\pgfplotsset{
my stackbar plot/.style={
xbar stacked,
xmin=0,xmax=100,
symbolic y coords={A,B},
ytick=data,
nodes near coords={xxx},}}
\begin{document}
\begin{tikzpicture}
\pgfplotstableread[col sep=space]{
text -- -
B 50 50
A 50.01 50
}\data
\pgfplotstablecreatecol[create col/expr={\thisrow{--}+\thisrow{-}}]{sum}\data
% normalize only if the sum is not 100
\pgfplotsinvokeforeach{--,-}{%
\pgfplotstablemodifyeachcolumnelement{#1}\of\data\as\wert{%
\pgfplotstablegetelem{\pgfplotstablerow}{sum}\of\data%
\pgfmathparse{\pgfplotsretval==100?\wert:\wert*100/\pgfplotsretval}%
\edef\wert{\pgfmathresult}
}%
}
\begin{axis}[my stackbar plot,]
\addplot table [x expr = \thisrow{--},y=text] {\data};
\addplot table [x expr = \thisrow{-}, y=text] {\data};
\end{axis}
\end{tikzpicture}
\end{document}
以同样的方式,可以只更改行中总计超过 100 的值,方法是使用
% normalize only if the sum is >100
\pgfplotsinvokeforeach{--,-}{%
\pgfplotstablemodifyeachcolumnelement{#1}\of\data\as\wert{%
\pgfplotstablegetelem{\pgfplotstablerow}{sum}\of\data%
\pgfmathparse{\pgfplotsretval<=100?\wert:\wert*100/\pgfplotsretval}%
\edef\wert{\pgfmathresult}
}%
}