2012-08-15 19 views
11

Ich versuchte mehrfarbige Texte zu implementieren, wie hier gezeigt:Multicolor Titel mit ggplot2 für R

multicolor text on chart

, die diese verwiesen:

multicolor text in R

Das ist, was ich kam mit (mit Hilfe von here):

require(ggplot2) 
require(grid) 
png(file="multicolortitle.png",width=800,height=500) 
qplot(x = hp,y = mpg,data = mtcars,color=factor(mtcars$cyl),size=2) + 
    scale_colour_manual(values = c("red3","green3","blue3")) + 
    theme_bw() + 
    opts(title = " \n ") + 
    opts(legend.position = "none") 
spacing <- 20 
grid.text(0.5, unit(1,"npc") - unit(1,"line"), 
      label=paste("4 cylinder,",paste(rep(" ",spacing*2), collapse='')), 
      gp=gpar(col="red3", fontsize=16,fontface="bold")) 
grid.text(0.5, unit(1,"npc") - unit(1,"line"), 
      label=paste(paste(rep(" ",spacing), collapse=''),"6 cylinder,", 
      paste(rep(" ",spacing), collapse='')), 
      gp=gpar(col="green3", fontsize=16,fontface="bold")) 
grid.text(0.5, unit(1,"npc") - unit(1,"line"), 
      label=paste(paste(rep(" ",spacing*2), collapse=''),"8 cylinder"), 
      gp=gpar(col="blue3", fontsize=16,fontface="bold")) 
grid.text(0.5, unit(1,"npc") - unit(2,"line"), 
      label=paste(paste(rep(" ",spacing*0), collapse=''), 
      "- Horsepower versus Miles per Gallon"), 
      gp=gpar(col="black", fontsize=16,fontface="bold")) 
dev.off() 

Hier ist der resultierende Graph:

Horsepower versus Miles per Gallon by # Cylinders (mtcars data-set)

Also, meine Frage: Gibt es eine elegantere Methode für diesen Einsatz? Ich möchte zum Beispiel in der Lage sein, ggsave zu verwenden, und das Erstellen des Abstands dafür ist ein sehr manueller Prozess - nicht geeignet für Szenarien, in denen ich Hunderte von Plots dieser Art automatisch erstellen muss. Ich könnte sehen, einige Funktionen darüber schreiben, aber vielleicht gibt es einen besseren Weg, um die Methoden mit der Basis-Plotting-Funktion verwendet zu implementieren?

+0

Möchten Sie die Farben automatisch die gleichen wie in der Handlung sein? –

+0

Ich denke, das wäre gut, vorausgesetzt, ich denke, du könntest einfach die 'Werte' in 'scale_colour_manual' einen Vektor machen und dann einfach Werte [1] usw. aufrufen, vielleicht anhängen, also wären es Werte [4]. Es wäre cool, wenn die Farben in der Handlung verwendet werden könnten, selbst wenn es nicht manuell ausgewählt würde, und ich bin mir nicht sicher, wie ich das machen würde, aber ich wette, das ist irgendwo dokumentiert: /. – ideamotor

+0

Willkommen in der R-Community von Stack Overflow! – Gregor

Antwort

6

Hier ist ein allgemeiner Ansatz, der einige zusätzliche Gitter Funktionen nutzt. Es ist nicht besonders gut poliert, aber es kann Ihnen einige nützliche Ideen geben:

library(grid) 
library(ggplot2) 

p <- ggplot(data=mtcars, aes(mpg,hp,color=factor(cyl),size=2)) + 
     geom_point() + theme_bw() + 
     opts(title = " \n ") + opts(legend.position="none") 

## Get factor levels 
levs <- levels(factor(mtcars$cyl)) 
n <- length(levs) 

## Get factors' plotting colors 
g <- ggplot_build(p) 
d <- unique(g$data[[1]][c("colour", "group")]) 
cols <- d$colour[order(d$group)] 

## Use widest label's width to determine spacing 
labs <- paste(levs, "cylinder") 
xlocs <- unit(0.5, "npc") + 
     1.1 * (seq_len(n) - mean(seq_len(n))) * max(unit(1, "strwidth", labs)) 

## Plot labels in top 10% of device 
pushViewport(viewport(y=0.95, height=0.1)) 
    grid.text(paste(levs, "cylinder"), 
       x = xlocs, y=unit(0.5, "lines"), 
       gp = gpar(col=cols, fontface="bold")) 
    grid.text("- Horsepower versus Miles per Gallon", 
       y = unit(-0.5, "lines")) 
upViewport() 

## Plot main figure in bottom 90% of device 
pushViewport(viewport(y=0.45, height=0.9)) 
    print(p, newpage=FALSE) 
upViewport() 
+0

danke, das ist großartig. es sieht so aus, als ob es automatisch funktioniert, wenn Sie mehr als 3 Gruppen im Titel haben – ideamotor