pgfplots: decorations (wie in Tikz) auf Funktionen

Tabellen und Grafiken erstellen und anordnen


guy.brush™
Forum-Century
Forum-Century
Beiträge: 185
Registriert: So 8. Aug 2010, 19:43
Wohnort: Earth

pgfplots: decorations (wie in Tikz) auf Funktionen

Beitrag von guy.brush™ »

Hallo,

es haben sich leider noch 2 weitere Fragen ergeben, da sie aber nicht in meinen anderen Thread passen, mache ich hier noch einen weiteren auf, in der Hoffnung, dass es irgendwann auch jemand anderem mal hilft :).

Zuerst einmal der Code:
\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows,calc,intersections,decorations.markings}
\usepackage{pgfplots}
\pgfplotsset{compat=1.4}

\begin{document}

\begin{figure}[!ht]
  \centering  
  \begin{tikzpicture}%[decoration={markings,
% 				    mark=at position 0.25 with {\arrow{>}},
% 				    mark=at position 0.5 with {\arrow{>}},
% 				    mark=at position 0.75 with {\arrow{>}}}]

    % Funktion
%       \draw[smooth,samples=100,domain=0.0:6.28319] plot[parametric] function{sin(2*t),sin(t)};
    \begin{axis}[axis lines=middle,
		  xmin=-2,
		  xmax=2,
		  ymin=-2,
		  ymax=2,
		  xtick={-1,1},
		  ytick={-1,1},
		  axis line style={->},
% 		  decoration={markings,
% 				    mark=at position 0.25 with {\arrow{>}},
% 				    mark=at position 0.5 with {\arrow{>}},
% 				    mark=at position 0.75 with {\arrow{>}}}
		]%,x=1cm,y=1cm]
      \addplot[smooth,samples=100,domain=0:2*pi,postaction={decorate}] ({sin(deg(2*x))}, {sin(deg(x))});
    \end{axis}
  \end{tikzpicture}
  \caption{foobar}
\end{figure}

\end{document}
Ich habe nun die folgenden Probleme: Ich möchte in dem Plot Pfeile (wie man es mittels ctions der tikz-library decorations.markings machen kann) auf den Pfad der Funktion zeichnen. Der Grund ist, dass die Richtung wichtig ist, in welcher man die Figur "abläuft". Leider funktioniert obiger Versuch so nicht. Weder als Argument von "tikzpicture" noch von "axis". Wenn ihr an einer Stelle das mal wieder einkommentiert, seht ihr, was für lustige Effekt das erzeugt :).

Die vorgegebenen Stellen, an denen ich die Pfeile gerade setzen möchte, sind erst einmal provisorisch zum Testen. Ich hatte zuerst die Funktion mit Tikz geplottet, aber ich dachte, es wäre sinnvoller, sie mit pgfplot dann zu machen. [Die tikz-Variante scheint zugriff auf gnuplot zu brauchen, obwohl ich nicht sehe, wieso :).]

Das 2. Problem ist, dass ich nicht weiß, wie ich die (und eigentlich nur die) Labels "-1" und "1" an der y-Achse verschieben soll. Wären es nodes, hätte ich "above left" bzw. "below left" verwendet und ggf. noch mit "above left=4.2mm" noch mehr verschoben. Aber ich konnte im pgfplots manual jetzt nichts konkretes zu diesem Problem finden. Ich fand lediglich etwas zur rein horizontalen Verschiebung und das galt dann leider auch für alle ticklabels. In diesem Fall macht es nichts aus, alle y-tickslabels zu verschieben, aber ich halte es für keine schöne und allgemeingültige Lösung :).


Ich hoffe, es kann mir jemand helfen :).

Viele Grüße,

\\ guy.brush
Arch Linux - KDE - TeXLive - Kile - \me = Advanced Newbie

Interessensschwerpunkte: Mathematik- und Formelsatz sowie mathematische (Mikro-)Typographie
Offenes Problem: negierte \xarrow-Pfeile beliebiger Länge

feuersaenger
Forum-Fortgeschrittener
Forum-Fortgeschrittener
Beiträge: 91
Registriert: Mi 5. Okt 2011, 18:24
Wohnort: Rheinbach

Beitrag von feuersaenger »

Hallo Guy.Brush,

Zu Deiner eigentlichen Frage zu den decorations kann ich an dieser Stelle nur folgende Teilaspekte beitragen:

1. die richtige Stelle fuer die decorations in pgfplots waeren in der optionsliste fuer \addplot .

Ungluecklich: das \addplot verteilt seine optionen in diesem fall ungeschickt (ein bug vermutlich), sodass man 'every path/.style={postaction={decorate}}' angeben muss (s.u. im Beispiel). Wenn man every path umaendert, muss man den nachher wieder auf "leer" setzen (sonst wuerde die decoration wieder dekoriert und man haette ne endlosschleife).

2. tick labels werden einheitlich gemacht, d.h. entweder alle nach oben oder alle nach unten. Du kannst aber problemlos \node verwenden wie in untenstehendem Beispiel (mit extra description/.code={\node....}).

3. tikz kann funktionen sowohl mit als auch ohne gnuplot generieren (plot function == mit gnuplot). pgfplots kann ebenso beides.

Hier ist das gesamtbeispiel:

  \begin{tikzpicture}[]

    \begin{axis}[axis lines=middle,
        xmin=-2,
        xmax=2,
        ymin=-2,
        ymax=2,
        xtick={-1,1},
        ytick={-1,1},
        yticklabel=\ ,% this disables the standard tick label *text* (but not the line)
        extra description/.code={
            % this generates custom y labels to implement individual
            % styles for every tick:
            \node[below left] at (axis cs:0,-1) {$-1$};
            \node[above left] at (axis cs:0,1) {$1$};
        },
        axis line style={->},
      ]%,x=1cm,y=1cm]
      \addplot[samples=100,domain=0:2*pi,
        % tedious, but necessary: pgfplots accidentally resets the
        % "decorate" option at the beginning of the path (probably a
        % bug).
        % This is a work-around:
        every path/.style={
            postaction={decorate},
            every path/.style={},
        },
        decoration={markings,
                 mark=at position 0.25 with {\arrow{>}},
                 mark=at position 0.5 with {\arrow{>}},
                 mark=at position 0.75 with {\arrow{>}}}
        ] 
        ({sin(deg(2*x))}, {sin(deg(x))});
    \end{axis}
  \end{tikzpicture}
Ich hoffe, das hilft Dir weiter.

Mit liebem Gruss

Christian

feuersaenger
Forum-Fortgeschrittener
Forum-Fortgeschrittener
Beiträge: 91
Registriert: Mi 5. Okt 2011, 18:24
Wohnort: Rheinbach

Beitrag von feuersaenger »

PS

Ich hatte vergessen zu schreiben, dass Tikz wohl mit der 'smooth' option keine decorations malen kann. Das fuehrt sowohl bei tikz als auch bei pgfplots zu problemen.

guy.brush™
Forum-Century
Forum-Century
Beiträge: 185
Registriert: So 8. Aug 2010, 19:43
Wohnort: Earth

Beitrag von guy.brush™ »

Hallo Christian,

vielen Dank! :)

zu (1): Sollte ich zufällig einen Bug entdeckt haben, so freut es mich natürlich, wenn ich auch ein klein wenig Hilfe beitragen konnte, wenn ich schon so viele Fragen habe :).

zu (2): Vielen Dank für die Lösung! Sie ist auch nur in solchen Fällen notwendig, wo eben bei mittleren Achsen die Funktion die Labels überdeckt.

zu (3): Ich habe mich noch nicht entschieden, ob ich gnuplots verwenden soll oder bei pgf bleiben soll. pgf scheint (leider) die berechneten Werte nicht in einer Datei zu speichern, weshalb bei einem 2. Durchlauf (ohne Änderung am plot) dieselbe Zeit erneut zum Berechnen benötigt wird. Ich habe im pgfplots manual gelesen, dass man das Ganze auch extern lagern kann und dann eine extra .pdf Datei erzeugt wird. So sehr überzeugt mich der Weg auch noch nicht, da man bei jedem Mal die Datei löschen muss, wenn man etwas anpasst und ich auch nicht weiß, ob LaTeX wirklich 100%-ig an derselben Stelle die .pdf einfügt, wo sie hin soll (also, als wenn man keine .pdf einbinden würde). Ich hoffe, du verstehst, was ich meine :).

zu (2) und (3): Stehen diese Lösungen auch im manual? Falls nicht, so wäre zumindest meine Empfehlung, sie aufzunehmen. Insbesondere eine Implementierung der Pfeile auf dem Funktionspfad halte ich für hin und wieder als recht wichtig. :)


4 mini bis kleine Fragen noch:

(a) Ich habe einmal getestet und die Reihenfolge im optionalen Argument zu \addplot ist scheinbar unwichtig, also ob jetzt zuerst "every path/.style" oder zuerst "decorations={...}" aufgerufen wird, scheint egal zu sein. Ist das richtig so oder kann es doch zu Problemen kommen, wenn ich die "decorations={...}" zuerst aufrufe?

(b) Ich habe
yticklabel=\ ,% this disables the standard tick label *text* (but not the line)
durch
yticklabel,% this disables the standard tick label *text* (but not the line)
ersetzt und es scheint auch zu funktionieren. Wäre es schlecht(er), wenn ich die 2. Variante verwende bzw. kann es da eher zu Fehlern kommen als bei deiner Variante?

(c) Wie entscheidet das pgfplots wie geplottet wird bzgl. der Skalierung auf den Achsen? Genauer: Die Funktion wird hier eher so geplottet, dass 1 Strich auf der Achse 2 cm entfernt ist. Wenn ich praktisch einen 1:1 plot möchte, muss ich noch "x=1cm, y=1cm" bei den optionalen Argumenten der \begin{axis}[...]-Umgebung angeben.

Skaliert pgfplots so, dass z.B. eine optisch gute Größe für einen plot erreicht wird?

(d) Ich verstehe den Unterschied (teils mangels Übersetzungskünste :/) zwischen "\addplot" und "\addplot" noch nicht so ganz. Aktuell verstehe ich es so: Wenn ich zuerst "\addplot[foo]" und dann "\addplot+[bar]" aufrufe, dann hätte ich statt dem "\addplot+[bar]" auch "\addplot[foo, bar]" schreiben können. Wenn vor einem "\addplot+" kein "\addplot" kommt, dann gilt "\addplot" = \addplot+", da es keine Argumente gibt, die zusätzlich bei "\addplot+" schon übernommen werden können. Richtig so?



Als nächstes werde ich mir wohl ein wenig genauer die "quiver plots" anschauen, um ggf. Vektorfelder realisieren zu können. Implizite Funktionen kann ja scheinbar leider weder gnuplot noch pgf so wirklich (ohne größeren Aufwand).


Viele Grüße,

\\ guy.brush
Arch Linux - KDE - TeXLive - Kile - \me = Advanced Newbie

Interessensschwerpunkte: Mathematik- und Formelsatz sowie mathematische (Mikro-)Typographie
Offenes Problem: negierte \xarrow-Pfeile beliebiger Länge

feuersaenger
Forum-Fortgeschrittener
Forum-Fortgeschrittener
Beiträge: 91
Registriert: Mi 5. Okt 2011, 18:24
Wohnort: Rheinbach

Beitrag von feuersaenger »

Hallo guy.brush,

danke fuer das Feedback.

Du hast schon recht, dass eine menge pgfplots abbildungen das uebersetzen betraechtlich verlaengern. Aus genau dem Grund hatte ich die "external" lib entwickelt - das verringert den zeitlichen Aufwand ganz betraechtlich, ohne das man sich zu viele Gedanken machen muss.

Was das problem mit der Neuerstellung angeht hast Du ganz sicher recht: wenn sich eine Option im Plot oder vielleicht das zugrundeliegende Datenfile von Dir aktualisiert wird, sollte natuerlich auch die Abbildung ersetzt werden. Das Problem ist jedoch unabhaengig von pgfplots. Mit anderen Worten: falls Du gnuplot oder matlab nehmen wuerdest, haettest Du genau dieselbe Anforderung. Tatsaechlich ist mit gnuplot noch eine weitere Anforderung drin: die Skalierung. Denn wenn man \includegraphics[width=8cm]{gnuplotgraphics.pdf} macht, werden dort die Fonts mitskaliert. Das muss natuerlich einheitlich sein, damit nicht bei einem plot die fonts groesser sind als beim naechsten. Klar, Loesungen gibt es auch hier. Aber wenn wirklich das Neuerstellen nach aktualisieren Dein einziger Grund ist, empfehle ich aus eigener Erfahrung die Verwendung von tikz/pgfplots. Hinweis: falls Du "make" verwendest, werden aktualisierungen an datenfiles auch noch automatisch erkannt und die zugehoerigen externen Graphiken neu erstellt.

Deine Sorge mit der Platzierung der automatisch erstellten .pdfs kann ich gut verstehen - das waere auch eine Katastrophe, wenn sich dann was verschieben wuerde. Tatsaechlich ist das mit grosser Sorgfalt entwickelt und getestet worden. Solltest Du wieder alles Erwarten da Schwierigkeiten finden, wird das mit sehr hoher Prioritaet behoben. Die automatische Externalisierung ist - nebenbei bemerkt - die allereinfachste und verlaesslichste Methode, um Teile der Achsenbeschriftung von der bounding box auszuschliessen und mit dem Rest des Dokuments auszurichten (vgl. Section Alignment in pgfplots manual und das 'trim axis right' feature).

Zu Deiner Anregung des Anpassens des Manuals: ich habe mir Dein Beispiel "as-is" in meine todo liste uebernommen. Ich hoffe, dass ich auch den bug noch fixen kann. In jedem Fall nehme ich die Anregung gerne auf (muss noch sehen, wann ich es schaffe).

Zu Deinen Minifragen:
(a) Es ist fast immer egal, in welcher Reihenfolge optionen auftauchen - es sei denn, dass eine option die andere Ueberschreibt, dann natuerlich nicht (beispiel: 'sharp plot,smooth' aktiviert 'smooth' und deaktiviert 'sharp plot').

In Deinem Fall ist es -wie in den meisten anderen - egal.

(b) 'yticklabel,' geht auch, ja.

(c) pgfplots skaliert standardmaessig so, dass der plot innerhalb von 'width' und 'height' reinpasst -- und damit den angezeigten plot moeglichst gut darstellt. Das verzerrt eigentlich immer die Achsen.

Wenn Du die Seitenverhaeltnisse gerne gleich haettest (d.h. x unit = y unit), kannst Du "axis equal" angeben.

Das "axis equal" ist besser als "x=1m,y=1cm" weil es automatisch die Vorgegebene Breite/Hoehe ausnutzt und die tatsaechliche Groesse der Units darauf optimiert.

(d) Hier ist noch ein Missverstaendnis zwischen \addplot und \addplot+ : das "+" bezieht sich nicht auf den vorhergehenden plot, sondern auf das, was man ohne Angabe von Optionen haette.

Sprich: wenn Du \addplot {x} schreibst, wuerde der aus der momentan eingestellten "cycle list" irgendwelche Optionen holen -- z.B. 'blue,mark=*'.

Die Faelle sind:
A] \addplot {x} --> dasselbe wie \addplot[blue,mark=*] {x}
die optionen wurden aus der cycle list geholt (wir nehmen einfach mal an, dass 'blue,mark=*' der aktuelle eintrag der cycle list ist. Das ist er im allgemeinen nicht).

B] \addplot[red] {x} -> wird genauso verwendet; es kommen keine automatisch erstellten optionen dazu

C] \addplot+[thick] {x} --> dasselbe wie \addplot[blue,mark=*,thick] {x}
Das "+" bedeuted, dass die optionen aus der cycle list geholt werden sollen, und dass alles innerhalb der eckigen klammern noch angehaengt wird.

Viel Spass damit!

Mit liebem Gruss

Christian

feuersaenger
Forum-Fortgeschrittener
Forum-Fortgeschrittener
Beiträge: 91
Registriert: Mi 5. Okt 2011, 18:24
Wohnort: Rheinbach

Beitrag von feuersaenger »

PS

Ich habe den Bug behoben. In der naechsten stable kann man dann \addplot[decorate...] oder \addplot[postaction={decorate}] nutzen (ohne obigen work-around).

Antworten