简体   繁体   中英

How to format labels in ggplot2 legend?

I have a ggplot2 plot that groups data by two variables and I want to exercise some control over how the label text is formatted. This question is illustrated below using the Oxboys data set from the nlme package. I've added a column called 'label' to the data such that 'Subjects' are now uniquely identified by the combination of 'Subject' and 'label'. In the data that I'm actually working with, the two variables of interest are x,y coordinates that uniquely identify points on a grid, hence the odd suggestion for output formatting below.

Taking the top legend item as an example, how can we reformat this so that it displays: "10 10" or "10,10" or "10ºN, 10ºW"*? Is there some way to utilize sprintf() or can you think of another way entirely?

One workaround would be to create a single new column in the data frame to define the groups and provide the labels. Would that be less work than doing the formatting directly in gglpot?

library(nlme)
library(ggplot2)
df <- transform(Oxboys, label = Subject)
p <- ggplot(df, aes(x = Occasion, y = height,
                    group = interaction(Subject, label),
                    color = interaction(Subject, label)))
p + geom_line()

在此处输入图片说明

*Bonus points for an answer that changes the legend title.

One workaround would be to create a single new column in the data frame to define the groups and provide the labels.

There's nothing wrong with this, and it's implicitly what you're doing by using interaction . If you're wedded to interaction for some reason, you can specify a separator:

interaction(Subject, label, sep=" ") # 10 10

But it would be better to just do as you suggest and create an explicit column in your data:

df$Group <- paste(df$Subject, "N ", df$label, "W") # 10N 10W

Then you'd just use that in your aesthetic mapping. This would of course give the legend a title of "Group", but you can change the legend title by just naming the appropriate scale:

p + scale_color_discrete("Your Title")

You could also use revalue in Hadley's plyr package, which I believe was written for exactly this purpose.

library(plyr)

# Rename Subject column
replace.Subject <- sapply(levels(df$Subject), function(x) paste0(x, " N"))
df$Subject <- revalue(df$Subject, replace.Subject)

# Rename label column
replace.label <- sapply(levels(df$label), function(x) paste0(x, " W"))
df$label <- revalue(df$label, replace.label)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM