编辑

编辑

我遇到的问题是,在下面的图中,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}
  }%
}

相关内容