drei pgfplots nebeneinander mit gemeinsamer Legende darüber

Antwort erstellen


Diese Frage dient dazu, das automatisierte Versenden von Formularen durch Spam-Bots zu verhindern.
Smilies
:D :) :( :o :shock: :? 8) :lol: :-x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:

BBCode ist eingeschaltet
[img] ist eingeschaltet
[flash] ist ausgeschaltet
[url] ist eingeschaltet
Smilies sind eingeschaltet

Die letzten Beiträge des Themas

Ich habe die Datenschutzerklärung gelesen und bin damit einverstanden.

   

Wenn du eine Datei oder mehrere Dateien anhängen möchtest, gib die Details unten ein.

Ansicht erweitern Die letzten Beiträge des Themas: drei pgfplots nebeneinander mit gemeinsamer Legende darüber

von feuersaenger » Di 26. Aug 2014, 20:13

Du hast Recht, das ist schon umstaendlich und unschoen.

Besser waere es, es wuerde sofort funktionieren... ist aber leider nicht so einfach.

Allerdings hat mich Deine Antwort daran erinnert, dass man generell die image externalisierung der \ref's ausschalten kann!

Das geht z.B. mithilfe folgender einfacher Konfiguration (global fuer alle):
\documentclass[12pt, oneside, a4paper, listof=numbered, listof=leveldown]{scrreprt}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{tikz}

\usepackage{pgfplots}
\pgfplotsset{compat=newest,
          title style = { anchor = south, at = {(0.5,0)}, draw=black, fill=white },
          every axis legend/.append style={at = {(0.5,1.05)},
                                   anchor = south,
                                   legend columns = -1,
                                   no markers,
                                   nodes = {right, inner xsep=5pt},
                                   shape = rectangle,
                                   fill = white},
		  invoke before crossref tikzpicture={%
		  	\begingroup
		  	\tikzset{external/export next=false}%
		  }%
          }

\usepgfplotslibrary{external}

\tikzexternalize

\begin{document}

\begin{figure}[H]

\pgfplotslegendfromname{gemeinsame_legende1}

\begin{tikzpicture}   % Diagramm links

\pgfplotsset{
   ymajorgrids,
   width  = 0.3\textwidth,
   title = {links}
   }

\begin{axis}[
   axis y line* = left,
   axis x line = none,
   ylabel = {Beschriftung rechts}
   ]
\end{axis}

\begin{axis}[
   axis y line* = right,
   yticklabels = { }
   ]
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\tikzset{external/export next=false} % um Symbol von Legendeneintrag korrekt zu zeichnen
\begin{tikzpicture}   % Diagramm mitte

\pgfplotsset{
   ymajorgrids,
   width  = 0.3\textwidth,
   title = {mitte},
   yticklabels = { }
   }

\begin{axis}[
   axis y line* = left,
   axis x line = none
   ]
   \addplot [blue, smooth] {-2*x};
   \label{data:Signal1}
\end{axis}

\begin{axis}[
   axis y line* = right,
   legend to name=gemeinsame_legende1
   ]
   \addlegendimage{/pgfplots/refstyle=data:Signal1}
   \addlegendentry{langer Legendeneintrag}
   
   \addplot [cyan, smooth] {2*x};
   \addlegendentry{noch ein langer Legendeneintrag}
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\begin{tikzpicture}   % Diagramm rechts

\pgfplotsset{
   ymajorgrids,
   width  = 0.3\textwidth,
   title = {rechts}
   }

\begin{axis}[
   axis y line* = left,
   axis x line = none,
   yticklabels = {},
   ]
\end{axis}

\begin{axis}[
   axis y line* = right,
   ylabel = {Beschriftung rechts}
   ]
\end{axis}
\end{tikzpicture}
\caption{gemeinsame Beschriftung für alle drei Graphen}
\end{figure}

\end{document} 
Mit liebem Gruss

Christian

von chris_Waechter » Mo 25. Aug 2014, 09:16

Guten Morgen,

die beiden von dir genannten Varianten finde ich zugegeben ziemlich umständlich, schade dass Latex oder PGFPlots da keine "Intelligenz" hat...

Ich habe aber noch ein wenig rumprobiert und scheinbar eine Lösung ohne Kommandozeile gefunden. Diese funktioniert in meinem Hauptdokument super, im Minimalbeispiel bekomme ich es aber nicht zum laufen.

Ich habe einfach den \pgfplotslegendfromname-Befehl in eine tikzpicture-Umgebung gepackt und die Externalisierung dafür abgeschalten. Wie gesagt, das Minimalbeispiel kann ich nicht kompilieren aber im Hauptdokument funktioniert es:
\documentclass[12pt, oneside, a4paper, listof=numbered, listof=leveldown]{scrreprt}

\usepackage{floatrow}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english, ngerman]{babel}

\usepackage{tikz}

\usepackage{pgfplots}
\pgfplotsset{compat=newest,
          title style = { anchor = south, at = {(0.5,0)}, draw=black, fill=white },
          every axis legend/.append style={at = {(0.5,1.05)},
                                   anchor = south,
                                   legend columns = -1,
                                   no markers,
                                   nodes = {right, inner xsep=5pt},
                                   shape = rectangle,
                                   fill = white}
          }

\usepgfplotslibrary{external}

\tikzexternalize[prefix=complierteAbbildungen/]
\tikzset{external/system call={lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"}}

\begin{document}

\begin{figure}[H]

\tikzset{external/export next=false}
\begin{tikzpicture} 
\pgfplotslegendfromname{gemeinsame_legende1}
\end{tikzpicture} 

\begin{tikzpicture}   % Diagramm links

\pgfplotsset{
   ymajorgrids,
   width  = 0.3\textwidth,
   title = {links}
   }

\begin{axis}[
   axis y line* = left,
   axis x line = none,
   ylabel = {Beschriftung rechts}
   ]
\end{axis}

\begin{axis}[
   axis y line* = right,
   yticklabels = { }
   ]
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\tikzset{external/export next=false} % um Symbol von Legendeneintrag korrekt zu zeichnen
\begin{tikzpicture}   % Diagramm mitte

\pgfplotsset{
   ymajorgrids,
   width  = 0.3\textwidth,
   title = {mitte},
   yticklabels = { }
   }

\begin{axis}[
   axis y line* = left,
   axis x line = none
   ]
   \addplot [blue, smooth] {-2*x};
   \label{data:Signal1}
\end{axis}

\begin{axis}[
   axis y line* = right,
   legend to name=gemeinsame_legende1
   ]
   \addlegendimage{/pgfplots/refstyle=data:Signal1}
   \addlegendentry{langer Legendeneintrag}
   
   \addplot [cyan, smooth] {2*x};
   \addlegendentry{noch ein langer Legendeneintrag}
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\begin{tikzpicture}   % Diagramm rechts

\pgfplotsset{
   ymajorgrids,
   width  = 0.3\textwidth,
   title = {rechts}
   }

\begin{axis}[
   axis y line* = left,
   axis x line = none,
   yticklabels = {},
   ]
\end{axis}

\begin{axis}[
   axis y line* = right,
   ylabel = {Beschriftung rechts}
   ]
\end{axis}
\end{tikzpicture}
\caption{gemeinsame Beschriftung für alle drei Graphen}
\end{figure}

\end{document} 

von feuersaenger » So 24. Aug 2014, 20:27

Hi Chris,

die image externalisierung wird speziell, wenn es um label/ref geht.

Langer rede kurzer Sinn ist: es funktioniert nicht mit dem standardmodus.

Du hast da zwei Optionen:

1. Du behaelst den standard externalisierungsmodus und musst dann aber den Befehl zur Externalisierung der legend "von Hand" eingeben.

Das ist nicht schwierig, nur umstaendlich:

Du schaust in Dein log file wo sowas wie
! Package tikz Error: Sorry, the system call 'lualatex -halt-on-error -interaction=batchmode -jobname "P-figure_crossref0" "\def\tikzexternalrealjob{P}\input{P}"' did NOT result in a usable output file 'P-figure_crossref0' (expected one of .pdf:.jpg:.jpeg:.png:). Please verify that you have enabled system calls. For pdflatex, this is 'pdflatex -shell-escape'. Sometimes it is also named 'write 18' or something like that. Or maybe the command simply failed? Error messages can be found in 'P-figure_crossref0.log'. If you continue now, I'll try to typeset the picture.
steht. Daraus kopierst Du von Hand den Befehl, in meinem Fall ist das
lualatex -halt-on-error -interaction=batchmode -jobname "P-figure_crossref0" "\def\tikzexternalrealjob{P}\input{P}"
Dann oeffnest Du eine Kommandozeile in dem Verzeichnis Deines Dokumentes (Windows explorer: rechts klick und dann "command shell here" oder so) und gibst diesen Befehl ein. Du kannst den Befehl auch in eine Datei "extra.bat" schreiben und diese durch doppelklick ausfuehren.

2. Die alternative geht unter linux fuer Experten gut, unter windows ist sie nix:
Es geht auch mit 'mode=list and make'. Falls Du weisst, was make ist, kannst Du das anwenden - ansonsten ist die Loesung vermutlich nur dann was, wenn Du auch linux benutzt.

Details dazu gibt es im Manual pgfmanual.pdf in dem Abschnitt zur Externalisierung.[/list]

PS.
Nur ein Hinweis, der vielleicht interessant ist:
Du musst nicht mehr
\tikzset{external/system call={lualatex...
eingeben: seit pgfplots 1.11 geht das automatisch.

von chris_Waechter » So 24. Aug 2014, 13:13

Hallo Chris und vielen Dank für den Tipp. Deine zweite Version funktioniert recht gut, aber nur solange ich die Externalisierung in der Präambel nicht anschalte. Kannst du dir das erklären?
\documentclass[12pt, oneside, a4paper, listof=numbered, listof=leveldown]{scrreprt}

\usepackage{floatrow}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english, ngerman]{babel}

\usepackage{tikz}

\usepackage{pgfplots}
\pgfplotsset{compat=newest,
			 title style = { anchor = south, at = {(0.5,0)}, draw=black, fill=white },
			 every axis legend/.append style={at = {(0.5,1.05)},
											  anchor = south,
											  legend columns = -1,
											  no markers, 
											  nodes = {right, inner xsep=5pt},
											  shape = rectangle,
											  fill = white}
			 }

\usepgfplotslibrary{external}

% Erzeugt einen Fehler
%\tikzexternalize[prefix=complierteAbbildungen/]

\tikzset{external/system call={lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"}}

\begin{document}

\begin{figure}[H]

\pgfplotslegendfromname{gemeinsame_legende1}

\begin{tikzpicture}	% Diagramm links

\pgfplotsset{
	ymajorgrids,
	width  = 0.3\textwidth,
	title = {links}
	}

\begin{axis}[
	axis y line* = left,
	axis x line = none,
	ylabel = {Beschriftung rechts}
	]
\end{axis}

\begin{axis}[
	axis y line* = right,
	yticklabels = { }
	]
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\tikzset{external/export next=false} % um Symbol von Legendeneintrag korrekt zu zeichnen
\begin{tikzpicture}	% Diagramm mitte

\pgfplotsset{
	ymajorgrids,
	width  = 0.3\textwidth,
	title = {mitte},
	yticklabels = { }
	}

\begin{axis}[
	axis y line* = left,
	axis x line = none
	]
	\addplot [blue, smooth] {-2*x};
	\label{data:Signal1}
\end{axis}

\begin{axis}[
	axis y line* = right,
	legend to name=gemeinsame_legende1
	]
	\addlegendimage{/pgfplots/refstyle=data:Signal1}
	\addlegendentry{langer Legendeneintrag}
	
	\addplot [cyan, smooth] {2*x};
	\addlegendentry{noch ein langer Legendeneintrag} 
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\begin{tikzpicture}	% Diagramm rechts

\pgfplotsset{
	ymajorgrids,
	width  = 0.3\textwidth,
	title = {rechts}
	}

\begin{axis}[
	axis y line* = left,
	axis x line = none,
	yticklabels = {},
	]
\end{axis}

\begin{axis}[
	axis y line* = right,
	ylabel = {Beschriftung rechts}
	]
\end{axis}
\end{tikzpicture}
\caption{gemeinsame Beschriftung für alle drei Graphen}
\end{figure}

\end{document}

von feuersaenger » So 24. Aug 2014, 00:03

Hi Chris,

es gibt da im Wesentlichen zwei Ansatzmoeglichkeiten.

Die mit weniger Anpassungsarbeit ist

1. Setze
legend style={overlay}
fuer die legende (d.h. in der Achse, wo Du die legende definierst). Damit wird die von der bounding box berechnung ausgeschlossen und nimmt gar keinen platz weg.

Dummerweise ueberschreibt sie dann jeglichen Text, der direkt ueber der Abbildung steht - was man normal nicht will. Das kann man aber leicht kompensieren, indem man darueber einen vspace einfuegt.

Dieser Ansatz koennte zu Problemen bei image externalisierung fuehren (denn dann wuerde die legend "aus dem externen bild fallen").

2. Du kannst
legend to name=chrislegendlabel
in der Achse setzen, die die legende definiert. Damit wird die legend _nicht_ gezeichnet, sondern lediglich "vermerkt".

Sobald Du dann irgendwo im Dokument
\ref{chrislegendlabel}
eingibst, wird an diese Stelle die legende gezeichnet.

Das ist robust und geht halbautomatisch auch mit image externalisierung. Du muesstest dann lediglich die horizontale Zentrierung "von Hand" machen (entweder ueber TeX builtin mittel wie \centering oder mithilfe von TikZ nodes).

Details zu beiden Ansaetzen findest Du im pgfplots manual in den Abschnitten zu Alignment (soweit es overlay betrifft) und zu Legenden (legend to name).

Mit liebem Gruss

Christian

drei pgfplots nebeneinander mit gemeinsamer Legende darüber

von chris_Waechter » Sa 23. Aug 2014, 13:29

Hallo,

ich habe drei Diagramme mit je zwei Achsen mit pgfplots die ich gerne nebeneinander anzeigen lassen möchte. Der Graph zeigt jedesmal das selbe nur unter anderen Einstellungen, daher möchte ich für alle Diagramme eine gemeinsame Legende nutzten. Die soll mittig über dem mittleren Diagramm stehen und die Legendeneinträge nebeneinander auflisten.

Bislang hat das auch wunderbar funktioniert. Heute habe ich aber einen etwas längeren Namen für den Legendeneintrag vergeben und festgestellt, dass die Graphen dann nicht mehr nebeneinander passen, weil die Legende über das Diagramm übersteht.

Kann man die Legende sonst noch irgendwie erzeugen, z.B. außerhalb des mittleren Diagramms damit wieder alles nebeneinander angezeigt wird?
\documentclass[12pt, oneside, a4paper, listof=numbered, listof=leveldown]{scrreprt}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english, ngerman]{babel}

\usepackage{tikz}

\usepackage{pgfplots}
\pgfplotsset{compat=newest,
			 width = 0.8\textwidth,
			 height = 0.3\textheight,
			 grid = none,
			 title style = { anchor = south, at = {(0.5,0)}, draw=black, fill=white },
			 every axis/.append style = {every node/.style = {{yshift = -8pt}, sloped}},
			 every x tick label/.append style = {text height = 2ex},
			 every tick/.append style = {scaled ticks = true},
			 every axis legend/.append style={at = {(0.5,1.05)},
											  anchor = south,
											  legend columns = -1,
											  no markers, 
											  nodes = {right, inner xsep=5pt},
											  shape = rectangle,
											  fill = white},
			 ybar/.append style = {every axis plot/.append style = {fill},
			 					   tick align = inside},
			 ybar interval/.append style = {every axis plot/.append style = {fill},
			 					   tick align = inside}
			 }

\begin{document}



\begin{figure}[H]
\begin{tikzpicture}	% Diagramm links

\pgfplotsset{
	ymajorgrids,
	width  = 0.3\textwidth,
	title = {Links}
	}

\begin{axis}[
	axis y line* = left,
	axis x line = none,
	ylabel = {Beschriftung links}
	]
\end{axis}

\begin{axis}[
	axis y line* = right,
	yticklabels = { }
	]
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\begin{tikzpicture}	% Diagramm mitte

\pgfplotsset{
	ymajorgrids,
	width  = 0.3\textwidth,
	title = {Mitte},
	yticklabels = { }
	}

\begin{axis}[
	axis y line* = left,
	axis x line = none
	]
	\addplot [blue, smooth] {x};
	\label{legendeneintrag}
\end{axis}

\begin{axis}[
	axis y line* = right,
	]
	\addlegendimage{/pgfplots/refstyle=legendeneintrag}
	\addlegendentry{langer Eintrag}
	
	\addplot [cyan, smooth] {-x};
	\addlegendentry{noch ein langer Eintrag} 
\end{axis}

\end{tikzpicture}
% keine Leerzeile, sonst sind Diagramme nicht nebeneinander
\begin{tikzpicture}	% Diagramm rechts

\pgfplotsset{
	ymajorgrids,
	width  = 0.3\textwidth,
	title = {rechts}
	}

\begin{axis}[
	axis y line* = left,
	axis x line = none,
	yticklabels = { }
	]
\end{axis}

\begin{axis}[
	axis y line* = right,
	ylabel = {Beschriftung rechts},
	]
\end{axis}

\end{tikzpicture}
\end{figure}



\end{document}

Nach oben