PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Schleife über Farben in pgfplots



Hobbykomiker
15-10-2013, 20:03
Huhu,

eigentlich habe ich mein Problem schon annähernd gelöst, aber vielleicht habe ich einen Denkfehler bei meiner ursprünglichen Herangehensweise gehabt und Ihr könnt mir sagen, wo er war. Ich weiß aus Jahr(zehnt)e langer LaTeX-Erfahrung, dass Fehler relativ häufig irgendwo zwischen meinen Ohren zu finden sind. :)

Bevor es losgeht, stelle ich erstmal meinen LaTeX-Rumpf hier ein, den ich für alles weitere verwendet habe:



\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}

<<< Code-Fragmente >>>

\end{tikzpicture}
\end{document}


Alle nachfolgenden Code-Schnipsel sind an der Stelle
<<< Code-Fragmente >>>
einzusetzen, um die Effekte, die ich hatte, (hoffentlich) nachzuvollziehen.

Bevor es zu meinem eigentlich Anliegen kommt, ein kleiner Effekt, den ich gerade hatte:

In den Beispielen des pgfplots-Manuals finde ich häufiger foreach-Schleifen der
Form (ist hier aber ein eigenes Beispiel)


\begin{axis} [domain=0:2,ymin=0,xmax=2]
\foreach \y in {0.3,0.6} { \addplot {\y*x} ; }
\end{axis}


Das liefert bei mir jedoch Unsinn, erst wenn ich die Laufvariable ändere
\y -> \ye funktioniert es. also:



\begin{axis} [domain=0:2,ymin=0,xmax=2]
\foreach \ye in {0.3,0.6} { \addplot {\ye*x} ; }
\end{axis}


Ich gehe natürlich davon aus, dass die Beispiele im Manual getestet worden sind, aber woran könnte es dann liegen?

Gut, kommen wir nun zu meinem eigentlichen "Problem".
Ich wollte eigentlich meinen Kurven in der foreach-Schleifen Farben zuordnen, etwa in der Art, wie es im pgfmanual (Kap. 56) mit "ball color" gezeigt wird:


\begin{axis} [domain=0:2,ymin=0,xmax=2]
\foreach \ye/\farbe in {0.3/red,0.6/blue} {
\addplot [color=\farbe] {\ye*x} ;
}
\end{axis}

Bei mir gibt es dann immer den Fehler


Undefined control sequence \end{axis}
Ich habe die unterschiedlichsten Varianten ausprobiert, aber nix hat funktioniert.

Komischerweise funktioniert dieses Minimalbeispiel, wenn man die foreach-Schleife um die axis-Umgebung packt (und natürlich ymax festsetzt):


\foreach \ye/\farbe in {0.3/red,0.6/blue} {
\begin{axis} [domain=0:2,ymin=0,ymax=1,xmax=2]
\addplot[\farbe] {\ye*x} ;
\end{axis} } ; %


An der einen oder anderen Stelle ließe sich das zwar so verwenden, aber irgendwie erscheint mir das nicht sinnvoll, da insbesondere andere Schleifenvariablen innerhalb der axis-Umgebung (bisher) problemlos laufen.

Nach einigem Suchen bin ich dann im pgfplots-Manual auf die 'cycle list', 'cycle list name', '\pgfplotscreateplotcyclelist' usw. gestoßen, die meinen
"Workaround" darstellen (der kann aber leider nicht alles, was ich will).

Ich habe mir also zuerst eine eigene 'cycle list' erstellt


\pgfplotscreateplotcyclelist{zweiFarben} %
{
{red},
{blue}
}
\begin{axis} [domain=0:2,ymin=0,xmax=2,cycle list name=zweiFarben]
\foreach \ye in {0.3,0.6} { \addplot {\ye*x} ; }
\end{axis}

Ok, das sieht gut aus, da ich aber schnell übermütig werde, habe ich dann gleich ausprobiert auch die Liniendicke und -art in die 'cycle list' auszulagern:

Folgender Code funktioniert allerdings nicht:


\pgfplotscreateplotcyclelist{zweiFarben} %
{
{red,very thick},
{blue,very thick}
}
\begin{axis} [domain=0:2,ymin=0,xmax=2,cycle list name=zweiFarben]
\foreach \ye in {0.3,0.6} { \addplot {\ye*x} ; }
\end{axis}


Der nächste Code funktioniert aber wieder:


\pgfplotscreateplotcyclelist{zweiFarben} %
{
{red,very thick},
{blue,very thick},
{magenta}
}
\begin{axis} [domain=0:2,ymin=0,xmax=2,cycle list name=zweiFarben]
\foreach \ye in {0.3,0.6} { \addplot {\ye*x} ; }
\end{axis}


Ich denke, der letzte Punkt mit den 'cycle list's fällt eher unter den Punkt "nice to know", es sei denn ich bin (wie so oft) von der gedachten Anwendung abgewichen. Dann würde ich um Aufklärung bitten.

Mein größtes "Problem" im Moment ist jedoch, dass die Anzahl der aufgerufenen \addplots, die die gleiche Farbe bekommen sollen, in der foreach-Schleife von weiteren Parametern abhängig sein können und somit nicht notwendigerweise bei jedem Schleifendurchlauf gleich ist. Bisher war das zwar der Fall, aber man möchte ja in die ferne Zukunft planen können :) ;)

Vielleicht gibt es ja auch eine andere (viel einfachere) Lösung oder zumindest andere Ansätze. :confused:

Thorsten

P.S.: Auf TikZ bin ich erst vor rund zehn, auf pgfplots vor gut sieben Wochen gestoßen (worden), ich würde mich also nicht als erfahrenen Anwender betrachtet, aber ich übe fleißig!!!!! :D

Feuersaenger
16-10-2013, 22:52
Hallo,

Du hast ja einige Fragen auf einmal - mal sehen, ob ich alle treffe.

Zu Deinem ersten Problem mit \y : pgfplots verwended bekanntlich 'x' als Laufvariable. Genauso verwendet es 'y' fuer 2d plots. Damit ist immer auch \x und \y reserviert. Es kann sogar sein, dass Du entsprechende Fehlermeldungen im log siehst (ich wuerde das erwarten/erhoffen).

Mit \foreach versus \addplot: hier kommt eine eigenschaft von pgfplots zutage, die einerseits sehr praktisch und andererseits (in Deinem Fall) sehr kompliziert ist: pgfplots geht erstmal durch alle \addplots durch und sammelt die Koordinaten in einer "survey" phase. Dabei werden ausschliesslich Koordinaten ausgewertet, aber nicht style optionen. Daher ist es erlaubt, dass \foreach variablen in Koordinaten (-expressions) auftauchen, sobald aber z.B. die Farbe davon abhaengt, muss man manuell die Expansion kontrollieren.

Konkret waere das


\foreach \ye/\farbe in {0.3/red,0.6/blue} {
\edef\TEMP{\noexpand\addplot [color=\farbe] {\ye*x} ;}
%\show\TEMP
\TEMP
}

Dies hier macht eine "Expanded DEFinition" mit \edef: \TEMP wird definiert auf alles innerhalb der geschweiften Klammern, wobei jedes Macro solange expandiert wird, bis es nicht mehr geht. Ausnahme: alle Macros vor denen \noexpand steht, werden 1:1 uebernommen. Das Resultat kannst Du Dir anschauen, wenn Du \show\TEMP einkommentierst. Als Daumenregel sollte \noexpand vor jedes Makro, das nicht von der Schleife abhaengt, dann geht das immer. Das nachfolgende \TEMP "fuehrt das makro aus".

Auf die Weise weiss pgfplots ueberhaupt gar nicht, dass eine Schleife benutzt wurde - ohne die Konstruktion steht aber noch color=\farbe da drin, obwohl nach der survey phase \farbe gar nicht mehr definiert ist.

Zu den cycle lists weiss ich aufgrund der soeben fortgeschrittenen Uhrzeit nichts, aber es kann sein, dass der "%" am Ende jeder Zeile (ohne Leerzeichen davor!) erwartet. Kann sein, dass pgfplots da was verbesserungsfaehig ist. Vielleicht gibt da auch das manuel mit den vordefinierten cycle lists aufschluss.

Mit liebem Gruss

Christian

Hobbykomiker
17-10-2013, 08:57
Hai,

erstmal vielen Dank für die schnelle Antwort. In meiner Testdatei funktioniert das schon mal prima!!

Ich habe mich zwar noch nie in die "Niederungen" der TeX-Anweisungen vorgewagt und mich nicht ernsthaft mit dem Themengebiet rund ums Expandieren beschäftigt, aber nun habe ich zwei weitere Punkte auf meiner (La)TeX-Todo-Liste. :)

Gruß,
Thorsten

Feuersaenger
17-10-2013, 22:41
Hi,

freut mich, dass die Antwort hilft.

falls Du mal was ueber die "Niederungen" des TeX scriptes lernen willst, kann ich Dir ein paar Notizen dazu von mir empfehlen, die ich unter

http://pgfplots.sourceforge.net/

im Abschnitt "TeX Programming Notes: on programming in TeX" zur Verfuegung stelle. Darin wird auch \edef detailliert erklaert.

Beachte: das braucht man normal nicht; also nur bei Interesse.

Mit liebem Gruss

Christian