在ggplot

时间:2017-12-24 20:50:11

标签: r ggplot2 ggrepel

我正在尝试制作一个由书名和书籍作者组成的标签。我想在标签中强调标题,但不是作者。

这是MWE数据:

Title,Author,Pages,Date Started,Date Finished
underline('Time Travel'),'James Gleick',353,1/1/17,1/27/17
underline('The Road'),'Cormac McCarthy',324,1/28/17,3/10/17

此代码有效但不允许标题作者

library(ggplot2)
library(tidyverse)
library(ggrepel)
library(ggalt)

books.2017 <- read_csv('books_2017.csv')
books.2017$`Date Started` <- as.Date(books.2017$`Date Started`, "%m/%d/%y")
books.2017$`Date Finished` <- as.Date(books.2017$`Date Finished`, "%m/%d/%y")

ggplot(books.2017, aes(x=`Date Started`, xend=`Date Finished`)) +
  geom_dumbbell(aes(size=Pages),size_x=0, size_xend=0) +
  geom_text_repel(aes(label=paste(Title)), parse=TRUE)

当我尝试将geom_text_repel更改为:

geom_text_repel(aes(label=paste(Title,Author)), parse=TRUE)

我收到此错误:

Error in parse(text = as.character(lab)) : 
  <text>:1:26: unexpected string constant
1: underline('Time Travel') 'James Gleick'
                             ^

编辑标签看起来应该是这样的

tesplot

3 个答案:

答案 0 :(得分:7)

您需要形成有效的plotmath表达式qplot(1,1,geom="blank") + annotate("text", x=1, y=1, label='underline("this")*" and that"', parse = TRUE)

enter image description here

应用于您的数据集,这可能看起来像label=paste(Title, Author, sep="~"),其中~是一个不间断的空间plotmath分隔符。在修复了不可重现的示例后,这将给出

enter image description here

答案 1 :(得分:5)

看起来您正在尝试提取您的goodreads数据,并根据开始数据,结束数据和图书大小计算出您一年中阅读的图书数量。

要执行您的建议,您可以使用parse上的geom_text*(选项,为此,您必须创建一个包含sprintf()的解析字符串并将其传递给geom_text*( } label输入parse = TRUE

要添加换行符,您可以考虑使用plotmath::over()

parseLabel <- sprintf("over(%s,%s)",
                 gsub(" ", "~", books.2007$Title, fixed = TRUE),
                 gsub(" ", "~", books.2007$Author, fixed = TRUE))
parseLabel

或者,您可以使用下划线,但添加换行很棘手,因为plotmath()不直接支持在解析公式中使用换行符。

parseLabel <- sprintf("underline(%s)~\n~%s",
                      gsub(" ", "~", books.2007$Title, fixed = TRUE),
                      gsub(" ", "~", books.2007$Author, fixed = TRUE))
parseLabel

注意: Baptiste 在他的回答中正确地说明了这一点我只是使用我创建的示例数据集扩展他的工作。

好的,这是一个基于上述假设的简单示例。我希望这能指出你正确的方向。

注意:我附加了一个示例数据集供人们使用。

添加下划线

为了在文字中添加下划线,您可以在parse=true来电中设置geom_label*()来利用plotmath

使用plotmath wih geom_label

的简单示例
library(tidyverse) # Loads ggplot2
library(graphics)
library(ggrepel)
library(gtable)
library(ggalt)

# load test dataset
# ... See example data set
# books.2007 <- structure...

gp <- ggplot(books.2007)
gp <- gp + geom_dumbbell( aes(x = `Date Started`, 
                              xend = `Date Finished`, 
                              y = ISBN, 
                              size = as.numeric(Pages)), 
                          size_x = 0, size_xend = 0)

# Construct parseLabel using sprintf
parseLabel <- sprintf("underline(%s)~\n~%s",
                  gsub(" ", "~", books.2007$Title, fixed = TRUE),
                  gsub(" ", "~", books.2007$Author, fixed = TRUE))

gp <- gp + geom_label(aes(x = `Date Started`,
                          y = ISBN), 
                      label = parseLabel,
                      vjust = 1.5, hjust = "inward", parse = TRUE)
gp <- gp + labs(size = "Book Size")
gp

示例绘图输出

enter image description here

使用plotmath和geom_label_repel

的简单示例

NB。我个人的感觉是geom_text更容易使用,因为geom_label_repel需要计算开销来计算标签的位置。

## Construct parse string
##
##
parseLabel <- sprintf("underline(%s)~\n~%s",
                      gsub(" ", "~", books.2007$Title, fixed = TRUE),
                      gsub(" ", "~", books.2007$Author, fixed = TRUE))
parseLabel

rm(gp)
gp <- ggplot(books.2007)
gp <- gp + geom_dumbbell( aes(x = `Date Started`,
                              xend = `Date Finished`,
                              y = ISBN,
                              size = as.numeric(Pages)),
                          size_x = 0, size_xend = 0)
gp <- gp + geom_label_repel(aes(x = `Date Started`,
                                y = ISBN),
                            label = parseLabel,
                            # max.iter = 100,
                            parse = TRUE)
gp <- gp + labs(size = "Book Size")
gp

使用geom_text_repel

绘制输出示例

enter image description here

示例数据集:

books.2007 <- structure(list(Title = c("memoirs of a geisha", "Blink: The Power of Thinking Without Thinking", 
"Power of One", "Harry Potter and the Half-Blood Prince (Book 6)", 
"Dune (Dune Chronicles Book 1)"), Author = c("arthur golden", 
"Malcolm Gladwell", "Bryce Courtenay", "J.K. Rowling", "Frank Herbert"
), ISBN = c("0099498189", "0316172324", "034541005X", "0439785960", 
"0441172717"), `My Rating` = c(4L, 3L, 5L, 4L, 5L), `Average Rating` = c(4, 
4.17, 5, 4.38, 4.55), Publisher = c("vintage", "Little Brown and Company", 
"Ballantine Books", "Scholastic Paperbacks", "Ace"), Binding = c("paperback", 
"Hardcover", "Paperback", "Paperback", "Paperback"), `Year Published` = c(2005L, 
2005L, 1996L, 2006L, 1990L), `Original Publication Year` = c(2005L, 
2005L, 1996L, 2006L, 1977L), `Date Read` = c(NA_character_, NA_character_, 
NA_character_, NA_character_, NA_character_), `Date Added` = structure(c(13558, 
13558, 13558, 13558, 13558), class = "Date"), Bookshelves = c("fiction", 
"nonfiction marketing", "fiction", "fiction fantasy", "fiction scifi"
), `My Review` = c(NA_character_, NA_character_, NA_character_, 
NA_character_, NA_character_), `Date Started` = structure(c(13577, 
13610, 13634, 13684, 13722), class = "Date"), `Date Finished` = structure(c(13623, 
13647, 13660, 13689, 13784), class = "Date"), Pages = c("522", 
"700", "300", "145", "700")), .Names = c("Title", "Author", "ISBN", 
"My Rating", "Average Rating", "Publisher", "Binding", "Year Published", 
"Original Publication Year", "Date Read", "Date Added", "Bookshelves", 
"My Review", "Date Started", "Date Finished", "Pages"), row.names = c(NA, 
-5L), spec = structure(list(cols = structure(list(Title = structure(list(), class = c("collector_character", 
"collector")), Author = structure(list(), class = c("collector_character", 
"collector")), ISBN = structure(list(), class = c("collector_character", 
"collector")), `My Rating` = structure(list(), class = c("collector_integer", 
"collector")), `Average Rating` = structure(list(), class = c("collector_double", 
"collector")), Publisher = structure(list(), class = c("collector_character", 
"collector")), Binding = structure(list(), class = c("collector_character", 
"collector")), `Year Published` = structure(list(), class = c("collector_integer", 
"collector")), `Original Publication Year` = structure(list(), class = c("collector_integer", 
"collector")), `Date Read` = structure(list(), class = c("collector_character", 
"collector")), `Date Added` = structure(list(), class = c("collector_character", 
"collector")), Bookshelves = structure(list(), class = c("collector_character", 
"collector")), `My Review` = structure(list(), class = c("collector_character", 
"collector"))), .Names = c("Title", "Author", "ISBN", "My Rating", 
"Average Rating", "Publisher", "Binding", "Year Published", "Original Publication Year", 
"Date Read", "Date Added", "Bookshelves", "My Review")), default = structure(list(), class = c("collector_guess", 
"collector"))), .Names = c("cols", "default"), class = "col_spec"), class = c("tbl_df", 
"tbl", "data.frame"))

简单示例 - 无格式

为了完整起见,我将如何处理避免公式构造问题的问题。

gp <- ggplot(books.2007)
gp <- gp + geom_dumbbell( aes(x = `Date Started`, 
                              xend = `Date Finished`, 
                              y = ISBN, 
                              size = as.numeric(Pages)), 
                          size_x = 0, size_xend = 0)
t <- paste(books.2007$Title, "\n", books.2007$Author)
gp <- gp + geom_label(aes(x = `Date Started`,
                               y = ISBN),
                      label = t,
                      vjust = 1.5, hjust = "inward", parse = FALSE)
gp <- gp + labs(size = "Book Size")
gp

绘图输出

enter image description here

答案 2 :(得分:2)

如果斜体足够而不是下划线,则此问题可以变得更简单,因为grid::gpar()不支持下划线字体。以下是使用斜体的示例:

library(tibble)
library(ggplot2)

books.2017 <- 
  tribble(~Title,~Author,~Pages,~`Date Started`,~`Date Finished`,
       'Time Travel','James Gleick',353,'1/1/17','1/27/17',
       'The Road','Cormac McCarthy',324,'1/28/17','3/10/17')

ggplot(books.2017, aes(x = `Date Started`,
                       xend = `Date Finished`,
                       y = Title,
                       yend = Title)) +
  geom_segment(aes(size = Pages), 
               lineend = 'round') +
  geom_text(aes(label = Title),
            fontface = 'italic',
            vjust = -3.5) +
  geom_text(aes(label = Author),
            vjust = -2)