79 Stimmen

Ggplot2 Zwei-Zeilen-Label mit Ausdruck

Ich möchte ein Achsenetikett über zwei Zeilen mit einer expression()-Anweisung schreiben. Allerdings erlauben plotmath und expression dies nicht (z.B. erscheint untergestellter Text ganz rechts). Ich habe diese Diskussion von circa 2005 zu einem ähnlichen Problem gefunden, aber die Lösung, die sie anbieten, lässt sich nicht auf meine Anwendung in ggplot2 übertragen. Eine kürzlich gestellte Frage behandelt eine andere Form von mehrzeiligen Ausdrucksanweisungen, aber auch die dort bereitgestellte Lösung ist hier nicht anwendbar.

Beispiel:

p <- ggplot(mtcars, aes(x=wt, y=mpg))+
  geom_point()+
  xlab(expression(paste("Ein langer Text geht hier nur zu Illustrationszwecken \n für mein Gewicht "[berichtet])))
try(ggsave(plot=p, filename=, height=4, width=6))

ergibt ein Bild, bei dem das untergestellte "berichtet" nach rechts verlagert wird, während ich möchte, dass es neben dem vorherigen Wort sitzt. ggplot2 Zweizeiliges Label mit Expression

75voto

Drew Steen Punkte 15565

Ich denke, das ist ein Fehler. (Oder eine Folge der Tatsache, dass "mehrzeilige Ausdrücke nicht unterstützt werden", wie in dem von Ihnen verlinkten Gespräch angegeben).

Der Workaround, auf den Gavin Simpson anspielte, lautet:

#Für die Bequemlichkeit p als das unbeschriftete Diagramm neu definieren
p <- ggplot(mtcars,aes(x=wt,y=mpg))+geom_point()

#Verwendung von atop, um einen Zeilenumbruch vorzutäuschen
p + xlab(expression(atop("Ein langer Text für den Zweck", paste("meines Punktes zu veranschaulichen" [berichtet]))))

Bildbeschreibung hier eingeben

Es ist möglich, echte Zeilenumbrüche mit Indizes zu verwenden. Im kurzen Beispiel unten, das die gleiche Form wie Ihr Beispiel hat, wird der Index korrekt neben dem restlichen Text platziert, aber die beiden Textzeilen sind nicht korrekt zentriert:

p + xlab(expression(paste("Zeile1 \n Zeile2 a" [b])))

Bildbeschreibung hier eingeben

Ich denke, dass in beiden Fällen der Index falsch platziert ist, wenn die obere Textzeile länger ist als die untere Textzeile. Vergleichen Sie

p + xlab(expression(paste("abc \n abcd" [berichtet])))

Bildbeschreibung hier eingeben

p + xlab(expression(paste("abc \n ab" [berichtet])))

Bildbeschreibung hier eingeben

Der Index landet immer genau rechts vom rechten Ende der oberen Zeile.

p + xlab(expression(paste("abcdefghijklmnop \n ab" [berichtet])))

Bildbeschreibung hier eingeben

16voto

Valentin_Ștefan Punkte 5510

1) Lösung mit cowplot::draw_label()

Man könnte auch die Annotationsfunktion draw_label() aus dem Paket cowplot verwenden (wie in dieser Diskussion vorgeschlagen). Wir könnten cowplot::draw_label() für so viele Textzeilen aufrufen, wie wir haben. Wenn cowplot::draw_label() in Kombination mit cowplot::ggdraw() verwendet wird, kann es überall auf der Leinwand/Blatt mit Koordinaten von 0 bis 1 (relativ zur gesamten Leinwand) annotieren.

Man muss die Position der Annotation anpassen und genügend Platz für den benutzerdefinierten Achsentitel schaffen.

Beachten Sie, dass das Paket cowplot derzeit das Standard-GGPlot-Thema ändert. Verwenden Sie daher bei Bedarf theme_set() nach dem Laden des Pakets, wie hier erwähnt.

Beachten Sie auch, dass die Funktion cowplot::draw_label() ggplot2::annotation_custom() unter der Haube verwendet. Mehr dazu werde ich im zweiten Teil weiter unten erwähnen.

library(ggplot2)
library(cowplot)
#> 
#> Attaching package: 'cowplot'
#> The following object is masked from 'package:ggplot2':
#> 
#>     ggsave

# Wenn nötig, auf Standard-Thema zurücksetzen (cowplot ändert das Thema); 
# theme_set(theme_grey())

p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()
# Genügend Platz für den benutzerdefinierten Achsentitel schaffen
p <- p + 
  xlab("") + # leerer Titel
  # Rand anpassen (schieben Sie das Label nach unten, indem Sie einen breiteren oberen Rand erzwingen)
  theme(axis.title.x = element_text(size = 10, # auch Textgröße bei Bedarf anpassen
                                    margin = margin(t = 10, r = 0, b = 0, l = 0,
                                                    unit = "mm")))

# Die beiden Linien, die Sie auf dem Diagramm haben möchten
line_1 <- "Ein langer Textzweck"
line_2 <- expression(paste("zur Veranschaulichung meines Punktes" [berichtet]))
# Oder vermeiden Sie paste() (es ist eigentlich nicht erforderlich)
# line_2 <- expression("zur Veranschaulichung meines Punktes" [berichtet])

# Cowplot::draw_label zweimal aufrufen, um zwei Textzeilen zu plotten
ggdraw(p) + 
  draw_label(line_1, x = 0.55, y = 0.075) + # Verwenden Sie relative Koordinaten für die Positionierung
  draw_label(line_2, x = 0.55, y = 0.025)

Beachten Sie, dass cowplot::draw_label() auch in Kombination mit dem Deaktivieren der Beschnittung verwendet werden kann, coord_cartesian(clip = "off"), was das Zeichnen überall auf der Leinwand erlaubt. Dieses Mal verwenden wir nicht mehr die relativen Koordinaten, sondern diejenigen aus dem Plot/Daten (die absoluten Koordinaten):

# Andere zwei Ausdrücke
line_1b <- expression(bolditalic('Erste Linie'))
line_2b <- expression(integral(f(x)*dx, a, b))

p + coord_cartesian(clip = "off") + # erlaubt das Zeichnen überall auf der Leinwand
  draw_label(line_1b, x = 3.5, y = 8.2) + # Verwenden Sie absolute Koordinaten für die Positionierung
  draw_label(line_2b, x = 3.5, y = 6)

Erstellt am 2019-01-14 mit dem reprex-Paket (v0.2.1)


2) Lösung mit ggplot2::annotation_custom()

Wie erwähnt, ist cowplot::draw_label() eine Wrapper-Funktion für ggplot2::annotation_custom(). Anstelle von cowplot::draw_label() könnten wir daher direkt ggplot2::annotation_custom() in Kombination mit dem Deaktivieren der Beschränkung, coord_cartesian(clip = "off"), verwenden, das mit dem Zusammenführen von diesem Pull-Request verfügbar wurde.

Dieser Ansatz ist jedoch umfangreicher mit mehr Koordinatenargumenten und wir müssen grid::textGrob() verwenden.

# Ein paar andere Linien, die Sie auf dem Plot als OX-Achsenbeschriftung möchten
line_1c <- expression("Verschiedene Schriftarten:" ~ bolditalic("bolditalic") ~ bold("bold") ~ italic("italic"))
line_2c <- expression("dies" ~~ sqrt(x, y) ~~ "oder dies" ~~ sum(x[i], i==1, n) ~~ "Mathematischer Ausdruck")
# das ~~ fügt etwas mehr Platz als ~ zwischen den Komponenten des Ausdrucks hinzu

p + coord_cartesian(clip = "off") +
  annotation_custom(grid::textGrob(line_1c), xmin = 3.5, xmax = 3.5, ymin = 7.3, ymax = 7.3) +
  annotation_custom(grid::textGrob(line_2c), xmin = 3.5, xmax = 3.5, ymin = 5.5, ymax = 5.5)

Erstellt am 2019-01-14 mit dem reprex-Paket (v0.2.1)

14voto

Maurits Evers Punkte 49100

Das Paket ggtext bietet eine andere Option, indem es die Verwendung von HTML-Tags zur Formatierung/Anpassung von Beschriftungen und Text ermöglicht.

library(ggtext)
ggplot(mtcars, aes(wt, mpg)) +
  geom_point() +
  xlab("Ein langer Text dient hier nur zur Veranschaulichung meines Punktes Gewichtangegeben") +
  theme(axis.title.x = element_markdown())

Bildbeschreibung eingeben

13voto

baptiste Punkte 73413

Sie könnten diesen Trick verwenden,

library(gridExtra)
library(grid)

element_custom <- function() {
  structure(list(), class = c("element_custom", "element_text"))
}

element_grob.element_custom <- function(element, label="", ...)  {

  mytheme <- ttheme_minimal(core = list(fg_params = list(parse=TRUE, 
                                                         hjust=0, x=0.1)))
  disect <- strsplit(label, "\\n")[[1]]
  tableGrob(as.matrix(disect), theme=mytheme)
}

# Standardmethode ist unzuverlässig
heightDetails.gtable <- function(x) sum(x$heights)

ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_line() + 
  labs(x= "Erste~Zeile \n kursiv('und eine zweite') \n integral(f(x)*dx, a, b)")+
  (theme_grey() %+replace% theme(axis.title.x = element_custom()))

enter image description here

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X