ggplot中文本标签的下划线部分

Underline part of text label in ggplot

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

这是 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'
                             ^

编辑 标签应该看起来像这样

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

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

如果用斜体代替下划线就可以解决这个问题,因为 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)

您似乎在尝试拉下您的 goodreads 数据,并根据开始数据、结束数据和图书大小绘制出您一年中阅读的图书数量。

要执行您的建议,您可以在 geom_text*( 上使用 parse 选项,为此您必须使用 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 在他的回答中正确地强调了这一点我只是使用我创建的示例数据集扩展他的工作。

好的,这是一个基于上述假设的快速示例。我希望这能为您指明正确的方向。

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

添加下划线

为了给文本添加下划线,您可以通过在 geom_label*() 调用中设置 parse=true 来利用 plotmath

使用 plotmath 的简单示例 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

示例图输出

使用 plotmath 和 geom_label_repel

的简单示例

注意。我个人的感觉是 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

的示例绘图输出

示例数据集:

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

绘图输出