pgfplots: Rundungsprobleme korrigieren

pgfplots: Rundungsprobleme korrigieren

Ich hatte ein Problem mit verschwindenden Markern, da die Datensumme mehr als 100 betrug, während xmax auf 100 eingestellt war. Siehepgfplots: Knoten in der Nähe der Koordinaten fehlt aufgrund von Rundungsproblemen.

Wie in der Antwort auf die zitierte Frage geschrieben, habe ich versucht, das Problem zu umgehen, indem ich den Wert auf 100 normalisiert habe. Dies führte jedoch zu (viel kleineren) Rundungsfehlern in vorher korrekten Zeilen und nun verschwinden dort die Markierungen. Siehe das folgende Beispiel. Vor der Normalisierung ist die Spalte F betroffen, danach die Spalte B.

Wie kann ich in einemzuverlässigWie kann man dieses Rundungsproblem vermeiden? Oder zumindest eine klare Fehlermeldung erhalten. Ich habe eine ganze Reihe dieser Diagramme und möchte sie nicht ständig auf fehlende Markierungen überprüfen müssen.

\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} 

Bildbeschreibung hier eingeben

Antwort1

Hier ist eine Möglichkeit,\usepackage{xintexpr}:

  • \xinttheiexpr [d] ...\relaxerzeugt eine Festkommazahl mit dZiffern nach dem Dezimalzeichen, wobei deine Zahl ist d =1, 2, .... EsRundendas exakt berechnete Ergebnis.

  • \xinttheexpr trunc(..., d)\relaxmacht das gleiche, aber anstatt zu runden,kürzt. (Entschuldigen Sie die zweifelhafte Syntax bezüglich ides Rundens und nicht ides Abschneidens. Was passiert ist, dass einige \xinttheiexpr [d,trunc] ... \relaximplementiert werden sollten. Ich bin ratlos, welche Syntax ich wählen soll, weil ich nicht möchte, dass es zu ausführlich wird. Habe darüber nachgedacht [d↓]…).

Wir können dies insbesondere an Stellen verwenden, an denen Dinge zulässig sind, die durch reine Erweiterung funktionieren, wie \xinttheexpr, \xinttheiexprz. B. f-expandable. ( xintWas das genau bedeutet, erfahren Sie in der Dokumentation.)

Hier sind einige Kommentare, die selbst nach einigen Bearbeitungen, um sie weniger wortreich zu machen, niemand mehr verstehen kann, nicht einmal der Autor.

In der Summe für sumnewaddieren wir 4 Zahlen, die gerundet wurden. Jede (Festkomma-)Rundung führte zu einem absoluten Fehler von höchstens 5 10^-7, daher haben wir einen Fehler in der exakten Summe von höchstens 2 10^-6 = 0.02 10^-4. Wenn wir das jetzt auf 4 Ziffern runden, haben wir einen möglichen Fehler von 0.52 10^-4. Das bedeutet, dass es sich möglicherweise nicht um die korrekte Rundung der exakten Summe handelt, sondern off by 1um die Einheit an der letzten Stelle. Das, was S_exactwir hier diskutieren, ist , 100 (exact sum of the original data)/S_pgfplotswobei S_pgfplotsdie berechnete Summe ist pgfplots, daher liegt sie nahe bei 100.

Wenn die neu skalierten Summanden zuerst auf 6 Ziffern gekürzt würden, könnte ihre berechnete Summe im 4 10^-6=0.04 10^-4Vergleich zur tatsächlichen um höchstens kleiner sein. Wenn wir das wieder auf 4 Ziffern kürzen, sind wir off by 1im Vergleich zur Kürzung der exakten Summe höchstens bei der letzten Ziffer, haben aber den Vorteil, dass wir wissen, dass wir unter dem exakten Ergebnis liegen. Wenn das exakte Ergebnis genau ist 100, dann ist uns fast garantiert, dass dieses Verfahren immer ergibt 99.9999(es könnte 100nur ergeben, wenn alle Verhältnisse bei genau wären 6 digits– nun, eigentlich ist das der Fall, wenn die, sumdurch die wir dividieren, selbst genau ist 100).

Wie dem auch sei, hier ist der Code:

\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} 

Blockquote

verwandte Informationen