Gerade mit Referenz-Steigung in einen doppelt logarithmischen Plot in R eintragen

Ich stelle viele meiner Daten in Plots mit zwei logarithmischen Achsen dar. Oftmals kommt es in solchen Plots auf die Steigung der Kurve an, also den Exponenten eines Power laws. In solchen Fällen zeichne ich, zusätzlich zu den Daten, eine oder mehrere Geraden mit einer Referenz-Steigung ein. Dadurch kann der Betrachter abschätzen, in welchen Bereichen die Daten eher zu der einen oder der anderen Steigung tendieren. Ich fand es allerdings immer sehr mühsam diese Steigungen einzuzeichnen. Grund: Ein Teil der Anfangs- oder Endkoordinaten musste im logarithmischen Raum berechnet werden. Daher habe ich mir eine Funktion geschrieben, die mir anhand einer Anfangs-Koordinate, der Steigung, sowie einem Teil der Endkoordinate, den fehlenden Wert berechnet und die Referenz-Gerade in den Plot einzeichnet.

  1. Zunächst generiere ich Daten, die im doppelt-logarithmischen Plot eine Gerade ergeben:
    x = 1:1000
    y = x^-1.5
  2. Diese werden dann mit schön formatierten Achsen geplottet, wie im Artikel „Logarithmische Achsen in R-Plots formatieren“ beschrieben.
    library(package = "sfsmisc")
    #png("log-gerade.png", width=480, height=360)
    #par(cex =1.5, mar=c(4,4,0,0)+.01)
     
    plot(x, y, log="xy", xaxt="n", yaxt="n")
    sfsmisc::eaxis(side=1, at=10^c(0:3))
    sfsmisc::eaxis(side=2, at=10^c(-4,-2,0))
     
    #dev.off()
    Darstellung einer Potenz-Funktion in einem Plot mit zwei logarithmischen Achsen.
    Darstellung einer Potenz-Funktion in einem Plot mit zwei logarithmischen Achsen.
  3. Der Exponent der von mir verwendeten Potenzfunktion ist -1.5. Daher ist auch die Steigung der Geraden m = -1.5. Nun möchte ich zusätzlich eine Gerade mit der Steigung m = -1 in den Plot eintragen. Diese soll bei am Punkt (x1 = 101, y1 = 10-1) beginnen. Enden soll die Gerade bei x2 = 2*102. Gesucht ist also die Y-Koordinate des Endpunktes (y2).

    Nun kann man:

    1. Alle vorhandenen x- und y-Werte logarithmieren (da beide Achsen logarithmisch sind).
    2. Diese Werte können in die Gleichung für die Berechnung der Steigung eingesetzt werden.
    3. Nun muss die Gleichung nach x2 aufgelöst werden (oder: die Gleichung auflösen lassen).
    4. Im Anschluss muss der x2-Wert in den Exponenten genommen werden.
    5. Über den Plot-Befehl kann nun eine Gerade zwischen den beiden Punkten (x1, y1) und (x2, y2) eingezeichnet werden.

    Diese Vorgehensweise habe ich in der Funktion refline() zusammengefasst:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    refline <- function(x1=NA, y1=NA, x2=NA, y2=NA, m=1, add=T, ...) {
      # Welchen Achsen (des letzten plots) sind logarithmisch?
      logX = par("xlog")
      logY = par("ylog")
     
      # Werte der logarithmischen Achsen umrechnen
      if(!is.na(x1) && logX) {x1 = log(x1)}
      if(!is.na(x2) && logX) {x2 = log(x2)}
      if(!is.na(y1) && logY) {y1 = log(y1)}
      if(!is.na(y2) && logY) {y2 = log(y2)}
     
      # Bestimmung der fehlenden Variablen
      if(is.na(x1)) {
        x1 = (y1 - y2 + m * x2) / m
        print("X1 wird berechnet")
      } else if(is.na(x2)) {
        x2 = (y2 - y1 + m * x1) / m
        print("X2 wird berechnet")
      } else if(is.na(y1)) {
        y1 = y2 + m * (x1 - x2)
        print("Y1 wird berechnet")
      } else if(is.na(y2)) {
        y2 = y1 + m * (x2 - x1)
        print(paste("Y2 wird berechnet", y2))
      }
     
      # Werte der logarithmischen Achsen umrechnen
      if(!is.na(x1) && logX) {x1 = exp(x1)}
      if(!is.na(x2) && logX) {x2 = exp(x2)}
      if(!is.na(y1) && logY) {y1 = exp(y1)}
      if(!is.na(y2) && logY) {y2 = exp(y2)}
     
      # Einzeichnen
      if(add) {
        lines(x=c(x1, x2), y=c(y1, y2), ...)
      }
     
      # Ausgabe
      data.frame(
        x1, y1, x2, y2, m
        , xmin=min(x1, x2), xmax=max(x1, x2)
        , ymin=min(y1, y2), ymax=max(y1, y2)
      )
    }

    Die Besonderheiten der Funktion refline() sind:

    • Es wird automatisch die fehlende Koordinate bestimmt.
    • Es wird erkannt, welche der Achsen logarithmisch sind.
    • Wichtige Werte der Geraden werden bei Aufruf zurückgegeben. Im Anschluss können sie verwendet werden, z.B. um Texte an die Enden der Geraden zu schreiben.
    • Die Gerade wird (auf Wunsch: add=T) in den vorigen Plot eingetragen.
    • Grafik-Parameter werden an den Plot-Befehl weitergeleitet (...).

    Nun kann refline() genutzt werden, um die oben genannte Gerade (sowie eine weitere Gerade) in den Plot einzuzeichnen. Die Variablen rl1 und rl2 dienen dazu, die Anfangs- und End-Punkte zu speichern. Mit den gespeicherten Werten werden Anschluss die Texte positioniert.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    #png("log-gerade_2.png", width=480, height=360)
    #par(cex =1.5, mar=c(4,4,0,0)+.01)
     
    plot(x, y, log="xy", xaxt="n", yaxt="n")
    sfsmisc::eaxis(side=1, at=10^c(0:3))
    sfsmisc::eaxis(side=2, at=10^c(-4,-2,0))
     
    rl1 = refline(x1=1e1, y1=1e-1, x2=2e2, m=-1, col="red")
    text(x=rl1$x2, y=rl1$y2, labels=paste0(" Slope: ", rl1$m), adj=0, col="red")
     
    rl2 = refline(x1=8e0, y1=1e-2, x2=1e2, m=-2, col="blue")
    text(x=rl2$x2, y=rl2$y2, labels=paste0(" Slope: ", rl2$m), adj=0, col="blue")
     
    #dev.off()
    Darstellung einer Potenzfunktion mit einer Steigung von -1.5. Zusätzlich wurden Referenz-Steigungen von -1 und -2 eingezeichnet.
    Darstellung einer Potenzfunktion mit einer Steigung von -1.5. Zusätzlich wurden Referenz-Steigungen von -1 und -2 eingezeichnet.
  4. Hinweis: Als Parameter für die Funktion refline() muss ein vollständiges und ein unvollständiges Koordinaten-Tupel, sowie die gewünschte Steigung angegeben werden. Der Punkt (x2, y2) muss dabei nicht immer rechts vom Punkt (x1, y1) liegen. Vielmehr hängt es von den gewählten Werten ab, wie die Punkte zueinander liegen. Die Werte x1 und y1 bestimmen gemeinsam immer den einen Punkt und die Werte x2 und y2 gemeinsam den anderen Punkt.
  5. Wie ich oben bereits erwähnt habe, funktioniert die Berechnung des fehlenden Punktes der Gerade auch in Plots mit zwei linearen, oder nur einer logarithmischen Achse:
    Im Falle z.B. einer logarirhmischen Y-Achse werden dann nur die Y-Koordinaten logarithmiert. Hier einige Beispiele:

    # Linear
    plot(x, y)
    r1 = refline(x1=0, x2=500, y1=1, m=-0.0005, col="blue")
    text(x=r1$xmax, y=r1$ymin, labels=paste0(" Steigung: ", r1$m), adj=0)
     
    # Y-logarithmisch
    plot(x, y, log="y", yaxt="n")
    sfsmisc::eaxis(side=2, at=10^c(-4,-2,0))
    r2 = refline(x1=10, x2=500, y1=1, m=-0.002, col="red")
    text(x=r2$xmax, y=r2$ymin, labels=paste0(" Steigung: ", r2$m), adj=0)

Mathematische Gleichung nach einer bestimmten Variablen auflösen lassen

Manchmal möchte man eine mathematische Gleichung umstellen, bzw. nach einer der Variablen auflösen. Je nachdem wie kompliziert die Gleichung ist, oder wie lange man so etwas nicht mehr gemacht hat, kann das ganz schon lästig sein. Numerik-Software wie Mathematica können einem die Arbeit deutlich erleichtern. Einige der Mathematica-Funktionen stehen auch online auf www.WolframAlpha.com (Wikipedia) zur Verfügung. In diesem Artikel beschriebe ich, wie man eine einfache Formel nach einer einer Variablen auflösen lassen kann.

  1. Nehmen wir an, wir haben folgende Gleichung:
    a = b + x
  2. Diese Formel wollen wir nach x auflösen. Das Ergebnis ist hoffetlich jedem klar: Auf beiden Seiten -b, ergibt:
    a - b = x

    bzw.

    x = a - b
  3. In Mathematica könnte man diese Aufgabe mit der Funktion Solve lösen (siehe auch: „equation solving„).
    Solve[a==b+x, x]
  4. Gibt man diesen Befehl auf WolframAlpha ein, erhält man das gesuchte Ergebnis:
    Die auf WolframAlpha angezeigte Lösung für das Problem "Löse die Gleichung a = b + x nach x auf"
    Die auf WolframAlpha angezeigte Lösung für das Problem „Löse die Gleichung a = b + x nach x auf“
  5. Da es sich bei WolframAlpha um eine semantische Suchmaschine handelt, kann man auch ähnliche Sachen eingeben, wie z.B.:
    solution of a=b+x for x

Mathematische Formeln in Glossar-Einträgen verwenden

Ein Glossar hilft dem Leser, auf schnellem Wege eine kurze Erkläung für verwendete Fachbegriffe zu finden. In LaTeX ist es möglich, automatisch ein Glossar erzeugen zu lassen. Dazu erstellt man in der Präambel mit dem Befehl \newglossaryentry{LABEL}{} einen neuen Eintrag, und bindet ihn dann mit dem Befehl \gls{LABEL}, \Gls{LABEL}, \plspl{LABEL} oder \Glspl{LABEL} in den Text ein. Verwendet man allerdings mathematische Formeln im Namen des Glossar-Eintrags, so wird diese Formel in der Überschrift im Glossar nicht fett geschrieben. In diesem Artikel beschreibe ich, wie man Glossar-Einträge mit mathematischen Formeln korrekt formatieren kann.

Zunächst muss in der Präambel das Paket glossaries eingebunden werden.

% Glossaries-Paket sollte nach dem hyperref-Paket geladen werden.
% \usepackage[nonumberlist,acronym,toc,section]{glossaries}
\usepackage[toc]{glossaries}
\makeglossaries

Das Problem

Im Anschluss kann man einen Glossar-Eintrag hinzufügen (Hier z.B. zum Fixations-Index (Fst) aus der F-Statistik):

\newglossaryentry{Fst}{
  name        = {$F_{st}$-Wert},
  description = {Fixations-Index,...},
  sort        = {fst-wert}
}

Nun kann man den Eintrag im Text einbinden:

Ein Text, der den Begriff \gls{Fst} enthält.

Im Text selbst wird der Eintrag korrekt angezeigt:

Link zum Glossar-Eintrag, der in normaler Schriftgröße in den Text eingefügt wurde.
Link zum Glossar-Eintrag, der in normaler Schriftgröße in den Text eingefügt wurde.

In Glossar ist die Formel allerdings nicht Fett geschrieben:

Standardmäßig werden mathematische Formeln in den Überschriften der Glossareinträge nicht fett geschrieben.
Standardmäßig werden mathematische Formeln in den Überschriften der Glossareinträge nicht fett geschrieben.

Ein erster Lösungsversuch

Um nun auch die Formel fett zu schreiben, kann man den Befehl \bm aus dem gleichnamigen Paket (bm) verwenden (siehe auch Stackoverflow):

\usepackage{bm}
 
\newglossaryentry{Fst}{
  name        = {$\bm{F_{st}}$-Wert},
  description = {Fixations-Index,...},
  sort        = {fst-wert}
}

Nun wird auch der Begriff Fst aus der Mathe-Umgebung in der Überschrift des Glossar-Eintrags fett geschrieben:

In der Glossar-Überschrift wird mit Hilfe des Befehls \bm die Formel fett geschrieben.
In der Glossar-Überschrift wird mit Hilfe des Befehls \bm die Formel fett geschrieben.

Allerdings wird Fst nun auch innerhalb des laufenden Textes fett geschrieben:

Unter Umständen wird nach der Formatierung der Formel, die Formel auch im Text fett geschrieben.
Unter Umständen wird nach der Formatierung der Formel, die Formel auch im Text fett geschrieben.

Die Lösung

Nun soll die Formel nur in der Glossar-Überschrift, aber nicht im Text fett geschreiben werden. Dazu fügt man zusätzlich den text-key hinzu, ohne diesen mit \bm zu formatieren (siehe Stackoverflow):

\newglossaryentry{Fst}{
  text        = {$F_{st}$-Wert},
  name        = {$\bm{F_{st}}$-Wert},
  description = {Fixations-Index,...},
  sort        = {fst-wert}
}

Schlussbemerkungen

  • Wenn die Formel am Anfang steht, funktionieren die Befehle für die Großschreibung nicht mehr. \gls und \glspl können problemlos verwendet werden. Verwendet man allerdings \Gls oder \Glspl bekommt man folgende Fehlermeldung:

    ! Extra }, or forgotten $.

  • Wenn man Formeln im Namen des Glossar-Eintrags verwendet, muss man auf jedenfall darauf achten, dass ein Wert für die Sortierung angegeben ist. Das geht mit Hilfe des sort-Schlüssels.