pgfplots:正確的捨入問題

pgfplots:正確的捨入問題

我遇到了標記消失的問題,因為資料總和超過 100,而 xmax 設定為 100。pgfplots:由於舍入問題,坐標附近的節點丟失

正如在引用問題的答案中所寫的,我試圖透過將值標準化為 100 來避免該問題。請參閱以下範例。在歸一化之前,F 列受到影響,B 列之後受到影響。

我怎樣才能在一個可靠的如何避免這個舍入問題?或至少得到一個明確的錯誤訊息。我有很多這樣的圖,我不想一直檢查它們是否缺少標記。

\documentclass{scrreprt}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}
\pgfplotsset{
 my stackbar plot/.style={
             xbar stacked,
             xmin=0,xmax=100,
             symbolic y coords={A,B,C,D,E,F,G},
             ytick=data,
             nodes near coords={xxx},}}

\begin{document}
 \pgfplotstableread[col sep=space]{
 text   --  -    +       ++
 A      0.0 1.7 13.8    84.5
 B      0.0 0.6 20.1    79.3
 C      0.0 1.9 13.2    84.9
 D      0.0 1.6 27.9    70.5
 E      1.3 3.9 19.5    75.3
 F      0.0 1.4 15.0    83.7
 G      0.3 1.7 24.8    73.2
 }\data


\pgfplotstablecreatecol[create col/expr={\thisrow{--}+\thisrow{-}+\thisrow{+}+\thisrow{++}}]{sum}\data %
 \pgfplotstablecreatecol[create col/copy=--]{--o}\data
 \pgfplotstablecreatecol[create col/copy=-]{-o}\data
 \pgfplotstablecreatecol[create col/copy=+]{+o}\data
 \pgfplotstablecreatecol[create col/copy=++]{++o}\data
 \pgfplotstablecreatecol[create col/expr={100/\thisrow{sum}*\thisrow{--o}}]{--}\data
 \pgfplotstablecreatecol[create col/expr={100/\thisrow{sum}*\thisrow{-o}}]{-}\data
 \pgfplotstablecreatecol[create col/expr={100/\thisrow{sum}*\thisrow{+o}}]{+}\data
 \pgfplotstablecreatecol[create col/expr={100/\thisrow{sum}*\thisrow{++o}}]{++}\data
 \pgfplotstablecreatecol[create col/expr={\thisrow{--}+\thisrow{-}+\thisrow{+}+\thisrow{++}}]{sumnew}\data

\pgfplotstabletypeset[columns={text,sum}   ,precision=10,columns/text/.style={string type}]\data \quad
\pgfplotstabletypeset[columns={text,sumnew},precision=10,columns/text/.style={string type}]\data 

%\pgfplotstablesave{\data}{pgfplotstempout.dat}
\begin{tikzpicture}
\begin{axis}[my stackbar plot]
 \addplot table [x expr = \thisrow{--o},y=text] {\data};
 \addplot table [x expr = \thisrow{-o}, y=text] {\data};
 \addplot table [x expr = \thisrow{+o}, y=text] {\data};
 \addplot table [x expr = \thisrow{++o}, y=text] {\data};
\end{axis}
\end{tikzpicture}
\quad
\begin{tikzpicture}
\begin{axis}[my stackbar plot]
 \addplot table [x expr = \thisrow{--},y=text] {\data};
 \addplot table [x expr = \thisrow{-}, y=text] {\data};
 \addplot table [x expr = \thisrow{+}, y=text] {\data};
 \addplot table [x expr = \thisrow{++}, y=text] {\data};
\end{axis}
\end{tikzpicture}

\end{document} 

在此輸入影像描述

答案1

這是一種使用方法\usepackage{xintexpr}:

  • \xinttheiexpr [d] ...\relaxd產生一個小數點後帶有數字的定點數,其中d是 number d =1, 2, ...。它回合準確計算的結果。

  • \xinttheexpr trunc(..., d)\relax做同樣的事情,但不是四捨五入,它截斷。 (抱歉,對於i四捨五入的可疑語法,對於截斷,沒有可疑的語法i,正在發生的事情是\xinttheiexpr [d,trunc] ... \relax應該實現一些,我對選擇什麼語法感到困惑,因為我不希望它變得冗長,想到[d↓]...... )。

我們可以在允許純擴展工作的地方使用它,就像\xinttheexpr, \xinttheiexprf-expandable 一樣。 (請參閱xint文件以了解其確切含義)。

以下是一些評論,即使經過一些編輯以使其不再冗長,但現在連作者都無法理解。

在求和中,sumnew我們增加了 4 個已四捨五入的數字。每個(定點)舍入最多引入一個絕對誤差5 10^-7,因此我們的精確總和最多有一個誤差2 10^-6 = 0.02 10^-4。如果我們現在將其四捨五入為 4 位,則可能存在 的誤差0.52 10^-4。這意味著它可能不是精確總和的正確舍入,而是off by 1針對最後一位的單位。我們S_exact在這裡討論的是計算出的100 (exact sum of the original data)/S_pgfplots總和,因此它接近。 S_pgfplotspgfplots100

如果重新縮放的被加數首先被截斷為 6 位數字,則它們的計算總和最多可能比4 10^-6=0.04 10^-4實際總和小。如果我們再次將其截斷為 4 位數字,與精確總和的截斷相比,我們至多處於off by 1最後一位數字,但優勢是知道我們低於精確結果。如果精確的結果是精確的100,那麼我們幾乎可以保證這個過程總是會產生(只有當所有比率都精確時99.9999它才能產生——實際上,如果我們除以的 本身恰好是)。1006 digitssum100

無論如何,這是代碼:

\documentclass{scrreprt}
\usepackage{xintexpr}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepackage{pgfplotstable}
\pgfplotsset{
 my stackbar plot/.style={
             xbar stacked,
             xmin=0,xmax=100,
             symbolic y coords={A,B,C,D,E,F,G},
             ytick=data,
             nodes near coords={xxx},}}

\begin{document}
 \pgfplotstableread[col sep=space]{
 text   --  -    +       ++
 A      0.0 1.7 13.8    84.5
 B      0.0 0.6 20.1    79.3
 C      0.0 1.9 13.2    84.9
 D      0.0 1.6 27.9    70.5
 E      1.3 3.9 19.5    75.3
 F      0.0 1.4 15.0    83.7
 G      0.3 1.7 24.8    73.2
 }\data


\pgfplotstablecreatecol[create col/expr={\thisrow{--}+\thisrow{-}+\thisrow{+}+\thisrow{++}}]{sum}\data %
 \pgfplotstablecreatecol[create col/copy=--]{--o}\data
 \pgfplotstablecreatecol[create col/copy=-]{-o}\data
 \pgfplotstablecreatecol[create col/copy=+]{+o}\data
 \pgfplotstablecreatecol[create col/copy=++]{++o}\data
 \pgfplotstablecreatecol[create col/expr={\xinttheiexpr[6]
   100/\thisrow{sum}*\thisrow{--o}\relax}]{--}\data 
 \pgfplotstablecreatecol[create col/expr={\xinttheiexpr[6]
   100/\thisrow{sum}*\thisrow{-o}\relax}]{-}\data 
 \pgfplotstablecreatecol[create col/expr={\xinttheiexpr[6]
   100/\thisrow{sum}*\thisrow{+o}\relax }]{+}\data
 \pgfplotstablecreatecol[create col/expr={\xinttheiexpr[6]
   100/\thisrow{sum}*\thisrow{++o}\relax }]{++}\data 
 \pgfplotstablecreatecol[create col/expr={\xinttheiexpr [6]
 \thisrow{--}+\thisrow{-}+\thisrow{+}+\thisrow{++}\relax}]{sumnew}\data
 % better? or even without [4] to get 100 as rounded integer ?
 % \pgfplotstablecreatecol[create col/expr={\xinttheiexpr[4]
 % \thisrow{--}+\thisrow{-}+\thisrow{+}+\thisrow{++}\relax}]{sumnew}\data

\pgfplotstabletypeset[columns={text,sum}   ,precision=10,columns/text/.style={string type}]\data \quad
\pgfplotstabletypeset[columns={text,sumnew},precision=10,columns/text/.style={string type}]\data 

%\pgfplotstablesave{\data}{pgfplotstempout.dat}
\begin{tikzpicture}
\begin{axis}[my stackbar plot]
 \addplot table [x expr = \thisrow{--o},y=text] {\data};
 \addplot table [x expr = \thisrow{-o}, y=text] {\data};
 \addplot table [x expr = \thisrow{+o}, y=text] {\data};
 \addplot table [x expr = \thisrow{++o}, y=text] {\data};
\end{axis}
\end{tikzpicture}
\quad
\begin{tikzpicture}
\begin{axis}[my stackbar plot]
 \addplot table [x expr = \thisrow{--},y=text] {\data};
 \addplot table [x expr = \thisrow{-}, y=text] {\data};
 \addplot table [x expr = \thisrow{+}, y=text] {\data};
 \addplot table [x expr = \thisrow{++}, y=text] {\data};
\end{axis}
\end{tikzpicture}

\end{document} 

區塊引用

相關內容