pgfplots - Sowohl absolute als auch relative Werte anzeigen

pgfplots - Sowohl absolute als auch relative Werte anzeigen

In meinem Diagramm versuche ich, den relativen Wert neben den absoluten Werten anzuzeigen. Beispielsweise möchte ich für die Spalte ganz rechts 110 direkt unter 9,02*10^6 anzeigen. Eine andere Möglichkeit wäre eine Achse rechts mit „Beschleunigung“, die von 1 bis 110 reicht.

Und wie kann ich das Diagramm nach unten verschieben, sodass die Balken direkt an der Linie der X-Achse beginnen?

\begin{tikzpicture}
\begin{axis}[
    ybar,
        scale=0.9,
        axis x line= bottom,
        axis y line = left,
        x post scale = 1.5,
        enlargelimits=0.15,
        anchor=west,
        ylabel=Rays/second,
        symbolic x coords={Original, Linear Traverser, MT Linear Traverser, CPU kd-tree, GPU kd-tree},
        xtick=data,
        nodes near coords, 
        nodes near coords align={vertical},
        x tick label style={rotate=45,anchor=east, xshift=-0.1em, yshift=-0.01em},
]
\addplot coordinates {(Original, 81685) (Linear Traverser, 506326) (MT Linear Traverser, 1754330)
    (CPU kd-tree, 1873746) (GPU kd-tree, 9023256)};
\end{axis}
\end{tikzpicture}

Beispielbild

Antwort1

Zunächst einmal würde ich empfehlen, die Daten in Form einer Tabelle und nicht als Koordinatenliste bereitzustellen. Dadurch ist es viel einfacher, die Werte zu bearbeiten, und Sie können Daten aus einer Datei verwenden. Außerdem bevorzuge ich im Allgemeinen die Verwendung numerischer Indizes für die X-Position anstelle von symbolic x coords. Sie können x expr=\coordindexin den \addplot table [...]Optionen verwenden, um diese im Handumdrehen zu generieren, und Sie können den Text aus Ihren Daten mit der Taste als Markierungsbeschriftungen verwenden xticklabels from file. Auf diese Weise müssen Sie die Beschriftungen nur an einer einzigen Stelle ändern, wenn Sie sie ändern möchten.

Wenn Sie Ihre Datentabelle in ein Makro eingelesen haben, das \datatablemit dem \pgfplotstablereadBefehl aufgerufen wurde, können Sie eine neue Spalte mit den relativen Werten erstellen mit

% Get base value
\pgfplotstablegetelem{0}{Value}\of\datatable
% Calculate relative values
\pgfplotstablecreatecol[
    create col/expr={
        \thisrow{Value}/\pgfplotsretval*100
    }
]{Relative}{\datatable}

nodes near coordsUm diese Werte zusätzlich zu den absoluten Werten in Ihrer verfügbar zu machen , können Sie den Schlüssel verwenden visualization depends on=\thisrow{Relative} \as \relativevalue. Die Werte können dann mit abgerufen werden \relativevalue. Leider funktioniert dies nur, wenn das Diagramm direkt aus einer Datendatei erstellt wird, nicht aus einem Tabellenmakro. Am einfachsten ist es, die neue Datentabelle (die die neue RelativeSpalte enthält) in einer temporären Datei zu speichern, wobei \pgfplotstablesave[col sep=comma]{\datatable}{temptable.txt}( col sep=commaaufgrund der Leerzeichen in den Textbeschriftungen erforderlich) verwendet wird.

Dann können Sie Ihre Einstellungen so ändern, nodes near coordsdass beide Werte angezeigt werden. Ich habe siunitxdie Zahlen folgendermaßen gerundet und formatiert:

nodes near coords={%
    \pgfmathfloattofixed{\pgfplotspointmeta}%
    \num[round-mode=figures, round-precision=2]{\pgfmathresult}\\%
    \SI[round-mode=figures, round-precision=2]{\relativevalue}{\percent}%
}

Um die Darstellung auf der Y-Achse beginnen zu lassen, können Sie festlegen enlarge y limits=upper, ymin=0.

Aus all dem ergibt sich folgendes Diagramm:

\documentclass{article}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.7}
\usepackage{siunitx}

\begin{document}

\pgfplotstableread{
Name Value
Original 81685
{Linear Traverser} 506326
{MT Linear Traverser} 1754330
{CPU kd-tree} 1873746
{GPU kd-tree} 9023256
}\datatable

% Get base value
\pgfplotstablegetelem{0}{Value}\of\datatable
% Calculate relative values
\pgfplotstablecreatecol[
    create col/expr={
        \thisrow{Value}/\pgfplotsretval*100
    }
]{Relative}{\datatable}

\pgfplotstablesave[col sep=comma]{\datatable}{temptable.txt}

\begin{tikzpicture}
\begin{axis}[
        ybar,
        scale=0.9,
        axis x line= bottom,
        axis y line = left,
        x post scale = 1.5,
        enlargelimits=0.15,
        enlarge y limits=upper, ymin=0,
        anchor=west,
        ylabel=Rays/second,
        xticklabels from table={\datatable}{Name},
        xtick=data, ytick=\empty,
        visualization depends on=\thisrow{Relative}\as\relativevalue,
        nodes near coords={%
            \pgfmathfloattofixed{\pgfplotspointmeta}%
            \num[round-mode=figures, round-precision=2]{\pgfmathresult}\\%
            \SI[round-mode=figures, round-precision=2]{\relativevalue}{\percent}%
        },
        nodes near coords align={vertical},
        every node near coord/.append style={align=center},
        x tick label style={rotate=45,anchor=east, xshift=-0.1em, yshift=-0.01em},
]
\addplot [fill=gray] table [x expr=\coordindex, col sep=comma] {temptable.txt};
\end{axis}
\end{tikzpicture}
\end{document}

verwandte Informationen