Ich bin absolute Latex-Anfängerin und verzweifele seit einigen Tagen an einem Grafen für meine Bachelorarbeit. Er soll am Ende etwa so aussehen: alt text

Davon bin ich noch recht weit entfernt. Deshalb habe ich folgende Fragen:

  1. Wie kann ich die Balkenbeschriftungen zentrieren?
  2. Wie kann ich die X-Achse in zwei Teile unterteilen (jeweils TB, FB, IG und SFB für 3-Jährige und für 4-Jährige)? Ich habe etwas von einem groupplot-Befehl gelesen, wusste aber nicht, wie ich damit solch ein gestapeltes Balkendiagramm hinbekomme.
  3. Sehr gerne hätte ich durch den gesamten Graphen noch eine Linie bei 50 %, die das Zufallsniveau markiert. Ist das möglich?

Folgendes habe ich schon:

\documentclass[a4paper,12pt]{article}
\usepackage{graphicx}
\usepackage{tikz}
\usepackage{tabularx}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\pgfplotstableread[col sep=comma,header=false]{
TB,11,39
FB,23,26
IG,11,38
SFB,12,38
vTB,6,15
vFB,12,9
vIG,11,8
vSFB,17,1
}\data

\pgfplotstablecreatecol[
create col/expr={
    \thisrow{1} + \thisrow{2}
}
]{sum}{\data}

\pgfplotsset{
percentage plot/.style={
        point meta=explicit,
every node near coord/.append style={
    xshift=17pt,
    yshift=-5.15pt,
    anchor=east,
%       font=\footnotesize,
    color=black,
            align=center,
        text width=1cm,
    },
    nodes near coords={
        \pgfmathtruncatemacro\iszero{\originalvalue==0}
        \ifnum\iszero=0
%       \pgfmathprintnumber{\originalvalue}$\,\%$\\
    \pgfmathprintnumber[fixed zerofill,precision=0]{\pgfplotspointmeta}
        \fi},
 nodes near coords align={center},
        yticklabel=\pgfmathprintnumber{\tick}\,$\%$,
        ymin=-10,
        ymax=110,
 %        enlarge y limits={upper,value=0.1},
    visualization depends on={y \as \originalvalue}
 },
 percentage series/.style={
    table/y expr=(\thisrow{#1}/\thisrow{sum}*100),table/meta=#1
 }
 }

 \begin{tikzpicture}
 \begin{axis}[
    ybar stacked,
 %       axis on top,
 height=8cm,
 %    width=10cm,
    percentage plot,
 %   axis y discontinuity=crunch,
 bar width=0.65cm,
 symbolic x coords={TB,FB,IG,SFB,vTB,vFB,vIG,vSFB},
    xtick=data,
x tick label style={rotate=45, anchor=east, xshift=-1.5mm, yshift=-2mm},
%   ylabel={\#a},
%    enlargelimits=0.15,
 legend style={
    at={(0.5,-0.30)},
    anchor=south,
    legend columns=-2
 }
 ]
  \addplot table [percentage series=1] {\data};
  \addplot table [percentage series=2] {\data};

  \legend{\strut leere Box, \strut volle Box}
  \end{axis}
  \end{tikzpicture}

  \end{document}

gefragt 07 Apr '20, 13:05

JoanaLo's gravatar image

JoanaLo
3926
Akzeptiert-Rate: 0%

bearbeitet 07 Apr '20, 19:22

cis's gravatar image

cis
9.5k93459491


Wenn Du wenigstens compat=1.9 setzt, dann lässt sich der Code deutlich vereinfachen. Ab dieser Version ist stacked ignores zero=true automatisch gesetzt. Die aktuelle pgfplots Version ist allerdings 1.17. Beim eingefrorenen TL2019 ist sie 1.16, weshalb ich in den Beispielen diesen Wert für compat verwende.

alt text

\documentclass[a4paper,12pt]{article}
\usepackage{pgfplotstable}% lädt pgfplots, tikz, etw
\pgfplotsset{compat=1.16}% mindestens 1.9 und unbedingt vor allen anderen pgfplots Einstellungen setzen, alternativ geht auch compat=newest

\pgfplotsset{
  percentage series/.style={
    table/y expr=(\thisrow{#1}/\thisrow{sum}*100),
    table/meta=#1,
    table/x expr=\coordindex,
  },
  percentage plot/.style={
    axis line style={draw=none},% Achsen nicht zeichnen
    tick pos=lower,% y-Ticks links, x-Ticks unten
    tick align=outside,% Ticks nach außen antragen,
    tick style={draw=none},% aber nicht zeichnen
    % Beschriftung in Balken:
    nodes near coords,
    point meta=explicit,
    every node near coord/.append style={text=black},
    % Bereich und Beschriftung der y-Achse:
    ymin=0,ymax=100,
    ytick={0,20,...,100},
    yticklabel=\pgfmathprintnumber{\tick}\,$\%$,
    % Gitterlinien für y-Ticks
    ymajorgrids=true,
    grid style={gray}
  }
}

\pgfplotstableread[col sep=comma,header=false]{
  TB,11,39
  FB,23,26
  IG,11,38
  SFB,12,38
  TB,6,15
  FB,12,9
  IG,11,8
  SFB,17,1
}\data
\pgfplotstablecreatecol[
  create col/expr={\thisrow{1} + \thisrow{2}}
]{sum}{\data}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
  ybar stacked,
  width=13cm,
  height=10cm,
  percentage plot,
  bar width=0.65cm,
  % Bereich und Beschriftung der x-Achse:
  xmin=-.5,xmax=7.5,
  xtick=data,
  xticklabels from table={\data}{[index]0},
  % zusätzliche Markierungen an x-Achse
  minor xtick={-.5,3.5,7.5},
  minor tick length=1.5cm,
  minor x tick style={draw,/pgfplots/every axis grid},
  % zusätzliche Beschriftungen an x-Achse
  extra x ticks={1.5,5.5},
  extra x tick labels={3-jährige, 4-jährige},
  extra x tick style={
    major tick length=\pgfkeysvalueof{/pgfplots/minor tick length},
    tick label style={anchor=south},
  },
  % zusätzliche Beschriftung an y-Achse
  extra y ticks={50},
  extra y tick style={%
    tick label style={red},
    grid style={red}
  },
  % Legende
  legend style={
    at={(0.5,\dimexpr-\pgfkeysvalueof{/pgfplots/minor tick length}-.5cm\relax)},
    anchor=north,
    legend columns=-2
},
]
% Balken
\addplot table [percentage series=1] {\data};
\addplot table [percentage series=2] {\data};
%Legende
\legend{\strut leere Box,\strut volle Box}

\end{axis}
\end{tikzpicture}
\end{document}

Oder wenn die Markierung für das Zufallsniveau über die Balken gezeichnet werden soll:

alt text

\documentclass[a4paper,12pt]{article}
\usepackage{pgfplotstable}% lädt pgfplots, tikz, etw
\pgfplotsset{compat=1.16}% mindestens 1.9 und unbedingt vor allen anderen pgfplots Einstellungen setzen, alternativ geht auch compat=newest

\pgfplotsset{
  percentage series/.style={
    table/y expr=(\thisrow{#1}/\thisrow{sum}*100),
    table/meta=#1,
    table/x expr=\coordindex,
  },
  percentage plot/.style={
    axis line style={draw=none},% Achsen nicht zeichnen
    tick pos=lower,% y-Ticks links, x-Ticks unten
    tick align=outside,% Ticks nach außen antragen,
    tick style={draw=none},% aber nicht zeichnen
    % Beschriftung in Balken:
    nodes near coords,
    point meta=explicit,
    every node near coord/.append style={text=black},
    % Bereich und Beschriftung der y-Achse:
    ymin=0,ymax=100,
    ytick={0,20,...,100},
    yticklabel=\pgfmathprintnumber{\tick}\,$\%$,
    % Gitterlinien für y-Ticks
    ymajorgrids=true,
    grid style={draw=none}
  }
}

\pgfplotstableread[col sep=comma,header=false]{
  TB,11,39
  FB,23,26
  IG,11,38
  SFB,12,38
  TB,6,15
  FB,12,9
  IG,11,8
  SFB,17,1
}\data
\pgfplotstablecreatecol[
  create col/expr={\thisrow{1} + \thisrow{2}}
]{sum}{\data}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
  ybar stacked,
  width=13cm,
  height=10cm,
  percentage plot,
  bar width=0.65cm,
  % Bereich und Beschriftung der x-Achse:
  xmin=-.5,xmax=7.5,
  xtick=data,
  xticklabels from table={\data}{[index]0},
  % zusätzliche Markierungen an x-Achse
  minor xtick={-.5,3.5,7.5},
  minor tick length=1.5cm,
  minor x tick style={draw,/pgfplots/every axis grid},
  % zusätzliche Beschriftungen an x-Achse
  extra x ticks={1.5,5.5},
  extra x tick labels={3-jährige, 4-jährige},
  extra x tick style={
    major tick length=\pgfkeysvalueof{/pgfplots/minor tick length},
    tick label style={anchor=south},
  },
  % zusätzliche Beschriftung an y-Achse
  extra y ticks={50},
  extra y tick style={%
    tick label style={red},
    grid style={red}
  },
  % Legende
  legend style={
    at={(0.5,\dimexpr-\pgfkeysvalueof{/pgfplots/minor tick length}-.5cm\relax)},
    anchor=north,
    legend columns=-2
},
]
% wenn Linie über den Balken sein soll, muss sie zuerst angegeben werden
%\draw[red](current axis.west|-0,50)--(current axis.east|-0,50);
% Balken
\addplot table [percentage series=1] {\data};
\addplot table [percentage series=2] {\data};
%Legende
\legend{\strut leere Box,\strut volle Box}

\end{axis}
\end{tikzpicture}
\end{document}
Permanenter link

beantwortet 08 Apr '20, 10:13

esdd's gravatar image

esdd
17.8k274256
Akzeptiert-Rate: 62%

bearbeitet 09 Apr '20, 09:55

So ist es natürlich noch schön bereinigt. Ich hatte jetzt meins wesentlich als Korrektur / Rettung des Originals ausgearbeitet.

(08 Apr '20, 13:03) cis

Könnte man nicht einfach compat=newest verwenden. Ich nutze pgfplots bisher kaum, aber mir scheint das die einfachste Methode, um aktuell zu bleiben.

(09 Apr '20, 09:29) der_zornige_...
2

compat=newest geht natürlich auch, wenn die installierte pgfplots Version aktuell genug ist. Für mich ist das hier eher auch eine Erinnerung mit welcher Version ich den Screenshot erzeugt habe.

(09 Apr '20, 10:01) esdd

Der Code im Themenstart enthält schon einige professionelle Mittel bzw. sinnvolle Ansätze, ist aber teilweise schwierig nachzuvollziehen und vielfach unübersichtlich.

· Die Balkenbeschriftung in der Mitte sollte scheints ab Version 1.8 der Default sein (?). Letztes Beispiel hier: https://ipfs-sec.stackexchange.cloudflare-ipfs.com/tex/A/question/36114.html
Mit \pgfplotsset{compat=newest} wird das auch so. Allerdings müssen dann diese ganzen manuellen Verschiebungen, die im Code standen wieder rausgenommen wuerden.

· Die Zusatzbeschriftung ("3-jährige" usw.) kann man mit extra x ticks ergänzen. Die Trennlinien würde ich dann als draw einzeichnen.

· Was diese Linie "Zufallsniveau" angeht verhindert diese "point meta" Sache hartnäckig, dass man noch andere Arten addplots ergänzt; z.B. einen coordinates-plot, was hier am einfachsten wäre. Das tüftel ich jetzt nicht aus.
Diese Gerade lässt sich auch als draw ergänzen. Soll sie im Vordergrund stehen, schlage ich vor, entsprechende Layer-Ebenen zu definieren und eine scope-Umgebung zu verwenden.

€dit: Ok, wie mir gesagt wurde geht diese Ergänzung als coordinates-plot in der (sehr "einfachen"...) Form
\addplot[purple, tick] [nodes near coords={},sharp plot,stack plots=false,point meta=y] coordinates {(-1,30) (8,30)} node[pos=0, anchor=east, font=\tiny, align=left]{Zufalls-\\niveau};
rückt aber genauso, wie die einfachere draw-Version davon, nicht in den Vordergrund.
Je nachdem ob diese Linie vor oder hinter den Balken sein soll, wird man ggf. Layer-Ebenen definieren müssen.

PS: Wenn diese ganzen Bezeichnungen in der Datentabelle schon stehen, dann nicht zusätzlich sowas machen "symbolic x coords={TB,FB,IG,SFB,vTB,vFB,vIG,vSFB},". Bisschen Mühe geben, rausfinden wie man die Tabellendaten ausliest. Es ist nicht immer ganz trivial, aber intuitiv muss es irgendwie gehen (wenn man das Paket kennt). ;) Siehe Code unten:
xticklabels from table={\data}{[index]0}, xtick=data,
in Verbindung mit x expr=\coordindex.

PPS: Ich habe mir mal noch einen kleinen Spaß erlaubt und mit Hilfe der Seite
% Farben definieren % https://html-color-codes.info/colors-from-image/ \definecolor{myorange}{HTML}{FFD686} \definecolor{Myorange}{HTML}{F9BC00} \definecolor{myblue}{HTML}{A8C5E7} \definecolor{Myblue}{HTML}{5997D0}
die Farben des Ausgangsbildes ermittelt. :)

alt text

\documentclass[a4paper,12pt]{article}
%\usepackage{graphicx}
%\usepackage{tikz}
%\usepackage{tabularx}
\usepackage{pgfplotstable}
\usepackage{pgfplots}

% ================
% Problem  "nodes near cords in die Mitte" ist wohl ab v1.9 default; 
% siehe  https://ipfs-sec.stackexchange.cloudflare-ipfs.com/tex/A/question/36114.html
% \pgfplotsset{compat=1.9}  % geht
\pgfplotsset{compat=newest} % geht auch
% siehe aber auch unten "every node near coord/.append style={...}"
% ================

\begin{document}
% ================
% Farben definieren
% https://html-color-codes.info/colors-from-image/
\definecolor{myorange}{HTML}{FFD686} 
\definecolor{Myorange}{HTML}{F9BC00} 
\definecolor{myblue}{HTML}{A8C5E7} 
\definecolor{Myblue}{HTML}{5997D0} 
% Diagrammdaten erzeugen
\pgfplotstableread[col sep=comma,header=false]{
TB,11,39
FB,23,26
IG,11,38
SFB,12,38
vTB,6,15
vFB,12,9
vIG,11,8
vSFB,17,1
}\data

\pgfplotstablecreatecol[
create col/expr={\thisrow{1} + \thisrow{2}}
]{sum}{\data}
% Tabelle ansehen: 
% \pgfplotstabletypeset[string type]{\data}

\pgfplotsset{
percentage series/.style={
table/y expr=(\thisrow{#1}/\thisrow{sum}*100),
table/meta=#1,
table/x expr=\coordindex,
}   }
% ================

% Weitere Einstellungen: 
\pgfplotsset{
percentage plot/.style={
point meta=explicit,
every node near coord/.append style={text=black,
% Diese Einstellungen verhindern wesentlich die Position der nodes near cords in der Mitte: 
%    xshift=17pt,
%    yshift=-5.15pt,
%    anchor=east,
%       font=\footnotesize,
%    color=black,
%            align=center,
%        text width=1cm,
},
nodes near coords={%
% ================
% Alle Zeilenenden hier auskommentieren, sonst diverse Leerstellen...
\pgfmathtruncatemacro\iszero{\originalvalue==0}%
\ifnum\iszero=0%
%       \pgfmathprintnumber{\originalvalue}$\,\%$\\
\pgfmathprintnumber[fixed zerofill,precision=0]{\pgfplotspointmeta}%
\fi},
% ================
%nodes near coords align={center}, % hat m.E. hier keinen bes. Effekt
% ================
yticklabel=\pgfmathprintnumber{\tick}\,$\%$,
ymin=-10,
ymax=110,
%        enlarge y limits={upper,value=0.1},
visualization depends on={y \as \originalvalue}
},
}

\begin{tikzpicture}
\begin{axis}[
ybar stacked,
%       axis on top,
height=8cm,  %    width=10cm,
percentage plot,
%   axis y discontinuity=crunch,
bar width=0.65cm, 
% ================
% Immer versuchen nicht doppelt zu arbeiten: 
% Nicht
% symbolic x coords={TB,FB,IG,SFB,vTB,vFB,vIG,vSFB},
% sondern
xticklabels from table={\data}{[index]0},
xtick=data,
% was mit x expr=\coordindex (siehe oben) möglich wird.
% ================ 
x tick label style={rotate=45, anchor=east, xshift=-1.5mm, yshift=-2mm},
%    enlargelimits=0.15,
legend style={
at={(0.5,-0.5)},
anchor=south,
legend columns=-2    },
% Weitere Annotationen
xmin=-1, xmax=8, 
extra x ticks={2.5,7},
extra x tick labels={3-jährige, 4-jährige},
extra x tick style={
major tick length=0mm,
% Rumgeschiebe von oben rückgängig machen: 
tick label style={align=center, anchor=north, xshift=1.5mm, yshift=-14mm, rotate=-45}, 
},
clip=false,
]
\addplot[fill=myblue, draw=Myblue] table [percentage series=1] {\data};
\addplot[fill=myorange, draw=Myorange] table [percentage series=2] {\data};
\legend{\strut leere Box, \strut volle Box}

% "Zufallsniveau"
\draw[red, thick] (-1,50) node[anchor=east, font=\tiny, align=left] {Zufalls-\\niveau} -- (8,50);
%alternativ 
\addplot[purple, tick] [nodes near coords={},sharp plot,stack plots=false,point meta=y] coordinates {(-1,30) (8,30)} node[pos=0, anchor=east,  font=\tiny, align=left]{kein \\ Zufalls-\\niveau};

% Trennstrich x-Achse
\foreach \x in {-1,4,8}{\edef\temp{\noexpand
\draw[] (\x,-10) -- (\x,-25mm);
}\temp}
\end{axis}
\end{tikzpicture}
\end{document}
Permanenter link

beantwortet 07 Apr '20, 17:44

cis's gravatar image

cis
9.5k93459491
Akzeptiert-Rate: 29%

bearbeitet 08 Apr '20, 13:17

-1

Vielen, vielen, vielen Dank!! Das war mir eine sehr große Hilfe!!

Permanenter link

beantwortet 09 Apr '20, 12:02

JoanaLo's gravatar image

JoanaLo
3926
Akzeptiert-Rate: 0%

1

@JoanaLo Das ist keine Antwort auf Deine Frage. Wenn Du eine Antwort kommentieren möchtest, dann nutze den Kommentarbutton (»neuen Kommentar hinzufügen«) unter dieser. Wenn Du eine Antwort gut findest, kannst Du den Daumen-hoch anklicken. Das geht auch bei mehreren Antworten. Wenn eine Dein Problem löst, kannst Du sie akzeptieren (den Haken anklicken).

(09 Apr '20, 12:20) esdd

Oh, das wusste ich nicht! Danke für den Hinweis! :)

(09 Apr '20, 12:24) JoanaLo
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×730
×296
×39
×12
×8

gestellte Frage: 07 Apr '20, 13:05

Frage wurde gesehen: 7,522 Mal

zuletzt geändert: 09 Apr '20, 12:24