pgfplots: 丸めの問題を修正

pgfplots: 丸めの問題を修正

xmaxが100に設定されているのに、データの合計が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] ...\relaxは数値 であるd小数点以下の桁を持つ固定小数点数を生成します。dd =1, 2, ...ラウンド正確に計算された結果。

  • \xinttheexpr trunc(..., d)\relax同じことをしますが、丸めではなく、切り捨てるi(丸めには があり、i切り捨てにはがないという疑わしい構文で申し訳ありません。何が起こっているかというと\xinttheiexpr [d,trunc] ... \relax、いくつかは実装する必要があるということです。冗長になりたくないので、構文として何を選択するかで困っています。考えてみると[d↓]...)。

これは、特に、\xinttheexpr, \xinttheiexprf 展開可能など、純粋な展開によって機能するものが許可されている場所で使用できます。(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} 

引用ブロック

関連情報