Ggplot2 двухстрочная метка с выражением
Я хотел бы написать метку оси над двумя строками с помощью инструкции expression()
. Однако plotmath
и expression
не позволят этого (например, текст подстрочного текста отображается справа). Я нашел эту дискуссию около 2005 года аналогичной проблемы, но работа, которую они предлагают, не переводится в мое приложение в ggplot2. Недавний вопрос касался другой перестановки операторов многострочного выражения, но опять же предлагаемая работа здесь не применяется.
Пример:
p <- ggplot(mtcars,aes(x=wt,y=mpg))+
geom_point()+
xlab(expression(paste("A long string of text goes here just for the purpose \n of illustrating my point Weight "[reported])))
try(ggsave(plot=p,filename=<some file>,height=4,width=6))
дает изображение, в котором индекс "сообщено" вызывается справа, когда я хочу, чтобы он сидел рядом с предыдущим словом.
![ggplot2 two line label with expression]()
Ответы
Ответ 1
Я думаю, что это ошибка. (Или следствие того, что "многострочные выражения не поддерживаются", как указано в разговоре, к которому вы привязались).
Обходной путь, на который ссылается Гевин Симпсон:
#For convenience redefine p as the unlabeled plot
p <- ggplot(mtcars,aes(x=wt,y=mpg))+geom_point()
#Use atop to fake a line break
p + xlab(expression(atop("A long string of text for the purpose", paste("of illustrating my point" [reported]))))
![enter image description here]()
Можно использовать истинные разрывы строк с индексами. В приведенном ниже кратком примере, который имеет ту же форму, что и ваш пример, индекс правильно помещен рядом с остальной частью текста, но две строки текста не центрированы правильно:
p + xlab(expression(paste("line1 \n line2 a" [b])))
![enter image description here]()
Я думаю, что в обоих случаях индекс стоит неправильно, если верхняя строка текста длиннее нижней строки текста. Сравнить
p + xlab(expression(paste("abc \n abcd" [reported])))
![enter image description here]()
p + xlab(expression(paste("abc \n ab" [reported])))
![enter image description here]()
Подстрока всегда заканчивается выравниванием справа от правого конца верхней строки.
p + xlab(expression(paste("abcdefghijklmnop \n ab" [reported])))
![enter image description here]()
Ответ 2
Вы можете использовать этот трюк,
library(gridExtra)
library(grid)
element_custom <- function() {
structure(list(), class = c("element_custom", "element_text"))
}
element_grob.element_custom <- function(element, label="", ...) {
mytheme <- ttheme_minimal(core = list(fg_params = list(parse=TRUE,
hjust=0, x=0.1)))
disect <- strsplit(label, "\\n")[[1]]
tableGrob(as.matrix(disect), theme=mytheme)
}
# default method is unreliable
heightDetails.gtable <- function(x) sum(x$heights)
ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_line() +
labs(x= "First~line \n italic('and a second') \n integral(f(x)*dx, a, b)")+
(theme_grey() %+replace% theme(axis.title.x = element_custom()))
![введите описание изображения здесь]()
Ответ 3
1) Решение с помощью cowplot::draw_label()
Можно также использовать функцию аннотации draw_label()
из пакета cowplot
(предложенного в этом обсуждении). Мы можем вызвать cowplot::draw_label()
как можно больше строк текста. Когда cowplot::draw_label()
используется в сочетании с cowplot::ggdraw()
, он может комментировать где угодно на холсте/листе с координатами в диапазоне от 0 до 1 (относительно всего холста).
Нужно изменить положение аннотации и освободить достаточно места для пользовательского заголовка оси.
Обратите внимание, что пакет cowplot
настоящее время изменяет тему ggplot по умолчанию, поэтому, если необходимо, используйте theme_set()
после загрузки пакета, как упомянуто здесь.
Также обратите внимание, что функция cowplot::draw_label()
использует ggplot2::annotation_custom()
под капотом. Я расскажу об этом подробнее во второй части ниже.
library(ggplot2)
library(cowplot)
#>
#> Attaching package: 'cowplot'
#> The following object is masked from 'package:ggplot2':
#>
#> ggsave
# If needed, revert to default theme (cowplot modifies the theme);
# theme_set(theme_grey())
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()
# Make enough space for the custom two lines axis title
p <- p +
xlab("") + # empty label
# Tweak the margins (push the label down by forcing a wider top margin)
theme(axis.title.x = element_text(size = 10, # also adjust text size if needed
margin = margin(t = 10, r = 0, b = 0, l = 0,
unit = "mm")))
# The two lines we wish on the plot
line_1 <- "A long string of text for the purpose"
line_2 <- expression(paste("of illustrating my point" [reported]))
# Or avoid paste() (is not actually needed)
# line_2 <- expression("of illustrating my point" [reported])
# Call cowplot::draw_label two times to plot two lines of text
ggdraw(p) +
draw_label(line_1, x = 0.55, y = 0.075) + # use relative coordinates for positioning
draw_label(line_2, x = 0.55, y = 0.025)
![]()
Обратите внимание, что cowplot::draw_label()
также можно использовать в сочетании с установкой отсечения, coord_cartesian(clip = "off")
, coord_cartesian(clip = "off")
, который позволяет строить в любом месте на холсте. На этот раз мы больше не используем относительные координаты, а те из графика/данных (абсолютные координаты):
# Other two expressions
line_1b <- expression(bolditalic('First line'))
line_2b <- expression(integral(f(x)*dx, a, b))
p + coord_cartesian(clip = "off") + # allows plotting anywhere on the canvas
draw_label(line_1b, x = 3.5, y = 8.2) + # use absolute coordinates for positioning
draw_label(line_2b, x = 3.5, y = 6)
![]()
Создано в 2019-01-14 пакетом представлением (v0.2.1)
2) Решение с помощью ggplot2::annotation_custom()
Как уже упоминалось, cowplot::draw_label()
является оболочкой ggplot2::annotation_custom()
. Таким образом, вместо cowplot::draw_label()
мы могли бы напрямую использовать ggplot2::annotation_custom()
в сочетании с установкой отсечения off coord_cartesian(clip = "off")
, которое стало доступно после слияния этого запроса на извлечение.
Однако этот подход более многословен, с большим количеством координатных аргументов, и нам нужно использовать grid::textGrob()
.
# Some other two lines we wish on the plot as OX axis title
line_1c <- expression("Various fonts:" ~ bolditalic("bolditalic") ~ bold("bold") ~ italic("italic"))
line_2c <- expression("this" ~~ sqrt(x, y) ~~ "or this" ~~ sum(x[i], i==1, n) ~~ "math expression")
# the ~~ ads a bit more space than ~ between the expression components
p + coord_cartesian(clip = "off") +
annotation_custom(grid::textGrob(line_1c), xmin = 3.5, xmax = 3.5, ymin = 7.3, ymax = 7.3) +
annotation_custom(grid::textGrob(line_2c), xmin = 3.5, xmax = 3.5, ymin = 5.5, ymax = 5.5)
![]()
Создано в 2019-01-14 пакетом представлением (v0.2.1)