Hi fünfhaus,
Im Prinzip ist Dein Ansatz der Richtige; es gibt keine Option der Art "nutze bitte eine andere colormap, sobald der Wert <0 ist".
Allerdings kann man Deinen Ansatz durch einen Kniff so verbessern, dass Du nicht durch trial und error auf die richtige colormap koordinate kommen musst: Du kannst mit 'point meta min' und 'point meta max' den Bereich angeben, der fuer die colormap/colorbar verwendet wird.
Aufgrund Deiner Funktion kann man sofort sagen, dass point meta max=exp(0)-0.5 = 0.5. Man kann auch ausrechnen, dass point meta min<= exp(-2)-0.5 = -0.364664716763387 . Im Grunde ist es nicht so schlimm, wenn man da einen kleineren Wert als point meta min nimmt. Das ist die Kernidee: wir waehlen point meta min einfach so, dass Du den colormap uebergang "auf 0 eichen" kannst.
Sprich: wir nehmen den Bereich -0.5 : 0.5 . Dann ist die "0" genau in der Mitte. "Die Mitte" heisst, das die colormap Koordinate gerade 500 ist.
Ich wuerde empfehlen, dass Du mindestens einen Punkt abstand beim Uebergang einfuegst - nicht, dass sonst mal eine division durch Null auftritt.
Wir haetten damit
Code:
\pgfplotsset{colormap={blackwhite}{[1pt]
rgb255(0pt)=(255, 200, 0);
rgb255(500pt)=(255, 75, 0);
rgb255(501pt)=(0, 100, 255);
rgb255(1000pt)=(0, 255, 255)},
point meta min=-0.5, % ~ exp(-2)-0.5,
point meta max=0.5,}
Das sollte die Sache wesentlich vereinfachen, denke ich.
Beim Bearbeiten ist mir aufgefallen, dass am Uebergang eine unschoene gezackte Linie entsteht. Klar, das liegt am Sampling: wenn wir das auf einem Gitter auswerten und dann verbinden, gibt es sowas.
ABER: da Deine Funktion rotationssymmetrisch ist, koennte man das ganze auch in Polar koordinaten machen! Dann gaebe es keinen gezackten Uebergang. Im Grunde ist es nicht kompliziert, man muss nur aufpassen, dass man tatsaechlich das Bild nicht (wesentlich) aendert. Ich habe das mal fuer Dich gemacht; Du kannst entscheiden, ob Du das gebrauchen kannst oder nicht. Nochmal: Die Polarkoordinaten sind *unwichtig* fuer Deine eigentliche Frage, dies ist mehr ein potentielles Sahnehaeubchen.
Hier also die Idee: polarkoordinaten in 3d haben die Form (winkel, radius, z wert) . In Deinem Fall braeuchten wir winkel im Bereich 0:360 . Der Radius muesste so beschaffen sein, dass das Eingabegebiet dem Bereich -1:1 entspricht und die Funktion dieselben Werte annimmt. Nun, die Funktion laesst sich aufgrund ihrer Symmetrie sehr einfach in Polarkoordinaten angeben: der Radius ist immer r= sqrt(x^2 + y^2). Damit ist -x^2-y^2 = -r^2 . Wir muessen nur noch den Bereich -1:1 abbilden. Der maximale Radius waere fuer x=1, y=1 erreicht, d.h. r=sqrt(1^2+1^2) = sqrt(2). Folglich haben wir die Funktion
(winkel, radius, exp(-radius^2) -0.5)
wobei winkel=0:360, radius=0:sqrt(2) zu waehlen ist.
Zusammengenommen ergibt das das untenstehende Bild:
Code:
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{grid style={dashed}}
\begin{document}
\pgfplotsset{colormap={blackwhite}{[1pt]
rgb255(0pt)=(255, 200, 0);
rgb255(500pt)=(255, 75, 0);
rgb255(501pt)=(0, 100, 255);
rgb255(1000pt)=(0, 255, 255)},
point meta min=-0.5, % ~ exp(-2)-0.5,
point meta max=0.5,}
\begin{tikzpicture}[scale=1.25]
\begin{axis}[grid=major,colorbar]
\addplot3[surf,domain=0:360,z buffer=sort,domain y=0:sqrt(2),data cs=polar,samples=25] {exp(-y^2)-0.5};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}[scale=1.25]
\begin{axis}[grid=major,colorbar]
\addplot3[surf,domain=-1:+1,samples=25] {exp(-x^2-y^2)-0.5};
\end{axis}
\end{tikzpicture}
\end{document}
Das Resultat habe ich als Bild angehaengt; es enthaelt zunaechst meine Polarkoordinatendarstellung und dann unten Deine alte Funktion.
Von den Optionen her ist lediglich noch folgendes zu erlaeutern:
- data cs=polar sagt pgfplots, dass es mit eingabekoordinaten der Form X=winkel, Y=radius, Z = wert umzugehen hat
- z buffer=sort ist notwendig, da die automatische tiefensortierung nur fuer kartesische koordinaten klappt
Wie gesagt, falls Du "Sahnetoertchen" nicht magst, brauchst Du es nicht.
Gruss
Christian
Lesezeichen