Исправить заголовок легенды при использовании надстрочного индекса в более чем двух строках - R ggplot2 - PullRequest
0 голосов
/ 25 декабря 2018

Я строю карту своего учебного района, и у меня возникают проблемы с редактированием названия легенды.Мне нужно, чтобы это было «Прогнозируемая продуктивность фруктов в парах за 40 лет (фрукты га ^ -1), записанная в четырех строках. Я мог бы использовать bquote (), чтобы построить -1 как верхний индекс. Но он создал дополнительное пространство, которое я не могувыяснить, как его снять. Дополнительный пробел появляется только тогда, когда заголовок разделен на несколько строк. Кроме того, выражение (atop ()) создает верхний индекс, но как только я попытался разделить его на более чем две строки, он не показываетстроки три и четыре.

Это карта с дополнительным пробелом с использованием bquote () Map with the extra space in the legend title

Это карта с заголовком из четырех строк с использованием выражения (atop ()) enter image description here

Я пробовал разные решения, найденные в интернете, в том числе этот пост . Но все они строят четвертую строку с дополнительным пробеломили только нарисуйте первую или вторую строку.

Ниже приведен код, который я использую. Любая помощь приветствуется. Комментарии представляют собой разные попытки.*

library(sf) #sf = simple feature
library(ggplot2)
library(dplyr)

PAECM_fallows <-read.csv("spatial_dist_fallows.csv")
PAECM_fallows_sp <- st_as_sf(PAECM_fallows,coords = c("X", "Y"),crs = "+proj=longlat +datum=WGS84 +no_defs")

custom_bins_fruit = c(0,60,120,180,240,1400)
PAECM_fallows_fruit <- PAECM_fallows_sp %>% 
  mutate(prod_cat_fallow = cut(prod_40, breaks= custom_bins_fruit),
         age_cat_fallow = cut(age, breaks = c(11,17,22,29,60)))


prod_map_PAECM_fruit<-ggplot()+
  geom_sf(data = PAECM_fallows_fruit,aes(size = prod_cat_fallow), shape = 18, show.legend = "point")+
  scale_size_manual(values= c(2,3,4,5,6),
                  # name = "Projected fruit\nproductivity in\nfallows in 40 yrs \n(fruits ha^-1)",
                  name = bquote("Projected fruit\nproductivity in\nfallows in 40 yrs \n( fruits"*ha^-1*")"),
                  # name = expression(paste("Projected fruit productivity\nin fallows in 40 yrs\n"),bquote(paste("("*fruits~ha^-1*")"))),#(Fruits/ha)
                  name = expression(atop("Projected fruit",
                                     "productivity in",
                                     "fallows in 40 yrs",
                                     "( fruits ha"^-1,")")),
                  breaks= c(NA,"(0,60]","(60,120]","(120,180]","(180,240]","(240,1.4e+03]"),
                  labels= c("NA","\u2264 60","60 - 120","120 - 180","180 - 240","> 240"),
                  guide = guide_legend(override.aes = list(linetype = "blank", shape = 18, fill = NA)))+
  # labs(size = expression(atop("Projected fruit\nproductivity in\nfallows in 40 yrs\n(fruits"*ha^-1*")", sep="")))+ #comment name line at the scale_size_manual
  # labs(size = bquote("Projected fruit productivity \nin fallows in 40 yrs \n( fruits"*ha^-1*")"))+ #comment name line at the scale_size_manual
  ggplot2::theme_minimal()+
  ggplot2::theme(legend.text.align=0.5,
                 legend.title.align = 0.5,
                 plot.background = element_blank(),
                 panel.grid = element_line(colour = "white"),
                 panel.background = element_rect(fill = "grey87", color = "white"))+#,
  coord_sf(xlim = c(-68.45,-68.2), ylim = c(-11.05,-10.8))
prod_map_PAECM_fruit

Дополнительный вопрос.Как только я начал использовать цитату, я не мог выровнять текст заголовка с помощью темы (legend.title.align = 0.5), какие-либо другие идеи?

Ответы [ 2 ]

0 голосов
/ 15 января 2019

В качестве альтернативы вы можете использовать функции аннотации cowplot::draw_label() или ggplot2::annotation_custom().Я думаю, что объяснения об этих подходах, приведенные в двухстрочной метке ggplot2 с выражением , также полезны и здесь.

1) Решение с cowplot::draw_label()

library(ggplot2)
library(cowplot)
#> Warning: package 'cowplot' was built under R version 3.5.2
#> 
#> 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())

# Build a simple plot as example
p <- ggplot(mtcars, aes(x = wt, y = mpg, size = factor(gear))) + 
  geom_point() +
  labs(size = element_blank()) + # remove default legend title
  # Make enough space for the custom legend title by tweaking the right margin
  theme(legend.margin = margin(t = 0, r = 26, b = 0, l = 0, unit = "mm"))
  # Adjust further theme elements if needed, like text size, font, etc

# The lines of text and expression that constitute your custom legend title
lines <- list(
  "Projected fruit",
  "productivity in",
  "fallows in 40 yrs",
  expression("(fruits ha" ^-1 ~ ")")
)

# Using relative coordinates ranging from 0 to 1 (relative to the entire canvas).
# There is some guesswork with the coordinates until we get them right.
min_y <- 0.6
step <- 0.04 # dictates the line spacing; need to play with it until you get it right
ys <- seq(from = min_y + step * 4, to = min_y, by = -step)
x <- 0.87

# Add the annotations that will actually constitute the legend title.
gg <- ggdraw(p)
#> Warning: Using size for a discrete variable is not advised.
# Neglect the warning in this example.
for (i in 1:4){
  gg <- gg + draw_label(lines[[i]], x = x, y = ys[i])
}
gg

Обратите внимание, что cowplot::draw_label() также можно использовать в сочетании с отключением отсечения, coord_cartesian(clip = "off"), которое позволяет строить в любом месте холста (см. Следующий пример с ggplot2::annotation_custom()).В таком случае мы больше не используем относительные координаты, а только те из графика / данных (абсолютные координаты).


2) Решение с ggplot2::annotation_custom()

Обратите внимание, что cowplot::draw_label() использует ggplot2::annotation_custom() под капотом, так что это более или менее та же техника аннотации, но более многословная.Нам нужно отключить отсечение.На этот раз мы больше не используем относительные координаты, а те из графика / данных (абсолютные координаты).

Опираясь на приведенный выше пример сюжета p:

min_y <- 24
step <- 1 # dictates the line spacing; need to play with it until you get it right
ys <- seq(from = min_y + step * 4, to = min_y, by = -step)
x <- 6.2

# set clipping off - allows plotting anywhere on the canvas
pp <- p + coord_cartesian(clip = "off")
for (i in 1:4){
  pp <- pp + annotation_custom(grid::textGrob(lines[[i]]), 
                               xmin = x, xmax = x, ymin = ys[i], ymax = ys[i])
}
pp
#> Warning: Using size for a discrete variable is not advised.

Создано в 2019-01-15 Представить пакет (v0.2.1)

0 голосов
/ 26 декабря 2018

После некоторых других попыток я придумал следующее решение для заголовка легенды:

name = expression(atop("",
                       atop(textstyle("Projected fruit"),
                            atop(textstyle("productivity in"),
                                 atop(textstyle("fallows in 40 yrs"),
                                      atop(textstyle("(fruits ha"^-1*")"))))))),

Я использовал texttyle (), чтобы отобразить весь текст с одинаковым размером, иначе он будет отображаться меньшимкаждый раз atop () вызывался.Atop () создает пробел между первой и второй строкой, поэтому первая строка кода находится сверху ("", поэтому первая строка будет пустой.

Это последний код скарта ниже.

library(sf) #sf = simple feature
library(ggplot2)
library(dplyr)

PAECM_fallows <-read.csv("spatial_dist_fallows.csv")
PAECM_fallows_sp <- st_as_sf(PAECM_fallows,coords = c("X", "Y"),crs = "+proj=longlat +datum=WGS84 +no_defs")

custom_bins_fruit = c(0,60,120,180,240,1400)
PAECM_fallows_fruit <- PAECM_fallows_sp %>% 
  mutate(prod_cat_fallow = cut(prod_40, breaks= custom_bins_fruit),
     age_cat_fallow = cut(age, breaks = c(11,17,22,29,60)))


prod_map_PAECM_fruit_legend_test<-ggplot()+
  geom_sf(data = PAECM_fallows_fruit,aes(size = prod_cat_fallow), shape = 18, show.legend = "point")+
  scale_size_manual(values= c(2,3,4,5,6),
              name = expression(atop("",
                                     atop(textstyle("Projected fruit"),
                                          atop(textstyle("productivity in"),
                                               atop(textstyle("fallows in 40 yrs"),
                                                    atop(textstyle("(fruits ha"^-1*")"))))))),
              breaks= c(NA,"(0,60]","(60,120]","(120,180]","(180,240]","(240,1.4e+03]"),
              labels= c("NA","\u2264 60","60 - 120","120 - 180","180 - 240","> 240"),
              guide = guide_legend(override.aes = list(linetype = "blank", shape = 18, fill = NA)))+
  ggplot2::theme_minimal()+
  ggplot2::theme(legend.text.align=0.5,
             legend.title.align = 0.5,
             plot.background = element_blank(),
             panel.grid = element_line(colour = "white"),
             panel.background = element_rect(fill = "grey87", color = "white"))+#,
  coord_sf(xlim = c(-68.45,-68.2), ylim = c(-11.05,-10.8))
prod_map_PAECM_fruit_legend_test

enter image description here

...