2016-04-15 8 views
1

Ich habe 2 Plots der gleichen Sache, ausgenommen die Farben füllen die Balken sind unterschiedlich auf jedem Grundstück. Da die Legende in den verschiedenen Plots aufgrund der Größe der Namen unterschiedliche Breiten hat, wird das Verhältnis zwischen Graph und Legende auf jeder Plot unterschiedlich. Ich muss beide gleich aussehen lassen.ggplot2 Legende Breite und Legende Strings Größe

Dies ist ein Beispiel:

library(ggplot2) 

x = c(rep("a",20),rep("b",10)) 
y = c(x = c(rep("BIGTEXT",20),rep("EVENBIGGERTEXT",10))) 
df = data.frame(x,y) 

p1 = ggplot(df,aes(x,fill=x)) + geom_bar() 
p2 = ggplot(df,aes(y,fill=y)) + geom_bar() 

p1 
p2 

Antwort

3

Sie die gtable Breiten auf einen gemeinsamen Wert gesetzt,

library(gtable) 
library(grid) 
gl <- lapply(list(p1, p2), ggplotGrob) 

gwidth <- do.call(unit.pmax, lapply(gl, "[[", "widths")) 
gl <- lapply(gl, "[[<-", "widths", value = gwidth) 
gridExtra::grid.arrange(grobs=gl) 

Alternativ können Sie set the panel size auf einen festen Wert.

+1

sehr elegant, aber das Ergebnis der Legende Tasten in leicht unterschiedlichen Positionen zwischen den Plots. Gibt es eine Möglichkeit, die Breitengleichheit bis zur Legende gtable zu erzwingen? – user20650

+2

@ user20650 es ist sicherlich möglich, aber etwas fummelig, weil i) die ganze Sache schlecht dokumentiert ist (man könnte erwarten "legende.margin" oder "legende.justification", aber nein), ii) ggplot ändert sein Layout Struktur im Laufe der Zeit; iii) gtable hat sich nie auf eine bequeme Art und Weise mit Begründungen befasst, die immer tiefere Ebenen von verschachtelten gtables erfordern, die schwer zu navigieren sind. Die Frage war zu diesem Thema nicht spezifisch, daher bin ich mir nicht sicher, was der beabsichtigte Anwendungsfall ist. – baptiste

0

Following @ Baptistes Kommentar: Fiddly aber ja, es kann getan werden. Aber keine Garantie, dass dies in zukünftigen Versionen funktioniert. Die Lösung wurde von here übernommen, aber auch diese Lösung musste aktualisiert werden.

library(ggplot2) # v2.2.1 
library(gtable) # v0.2.0 
library(grid) 
library(gridExtra) # v2.2.1 

x = c(rep("a",20),rep("b",10)) 
y = c(x = c(rep("BIGTEXT",20),rep("EVENBIGGERTEXT",10))) 
df = data.frame(x,y) 

p1 = ggplot(df,aes(x,fill=x)) + geom_bar() 
p2 = ggplot(df,aes(y,fill=y)) + geom_bar() 

# Get the grobs 
gA <- ggplotGrob(p1) 
gB <- ggplotGrob(p2) 

# Get the widths of the legends 
index = which(gA$layout$name == "guide-box") 
leg1 <- convertX(sum(with(gA$grobs[[index]], grobs[[1]]$widths)), "mm") 
leg2 <- convertX(sum(with(gB$grobs[[index]], grobs[[1]]$widths)), "mm") 

# Add an empty column of width "abs(diff(c(leg1, leg2))) mm" to the right of 
# legend box for gA (the smaller legend box) 
gA$grobs[[index]] <- gtable_add_cols(gA$grobs[[index]], unit(abs(diff(c(leg1, leg2))), "mm")) 

# Set widths to maximums of corresponding widths 
gl <- list(gA, gB) 
gwidth <- do.call(unit.pmax, lapply(gl, "[[", "widths")) 
gl <- lapply(gl, "[[<-", "widths", value = gwidth) 


# Draw the plots 
grid.newpage() 
grid.draw(gl[[1]]) 

grid.newpage() 
grid.draw(gl[[2]])