Переменное выравнивание текстовых меток ggrepel на граненом аллювиальном графике - PullRequest
0 голосов
/ 13 мая 2019

Я пытаюсь создать ограненный аллювиальный график с метками для слоев на первой оси, смещенными влево и вправо, и метками справа, смещенными вправо и вправо.

# Small working example

# Install Packages and Libraries
install.packages("ggplot2")
install.packages("ggalluvial")
install.packages("ggrepel")
library(ggplot2)
library(ggalluvial)
library(ggrepel)

# Data Frame with 2 regions, 3 supply sectors and 3 demand sectors
df <- data.frame(region = c("A","A","A","B","B","B"),
                 supplySector = c("coal","gas","wind","coal","gas","wind"),
                 demandSector = c("resid","indus","ag","resid","indus","ag"),
                 value = 10*runif(6)); df    

# Faceted plot with ggrepel (nudge_x and hjust assigned for each label) works.
p <- ggplot(df, aes(y = value, axis1 = supplySector, axis2 = demandSector, group=region)) +
  ggalluvial::geom_alluvium(aes(fill = supplySector), width = 1/12, color="black", alpha=0.6) +
  ggalluvial::geom_stratum(width = 1/12, fill = "grey70", color = "grey10", alpha=1) +
  scale_x_discrete(limits = c("supplySector", "demandSector"), expand = c(0.3,0),drop=F) +
  facet_wrap(region~.) +
  ggrepel::geom_text_repel(stat = "stratum", label.strata = TRUE, direction = "y", 
                           size = 4, segment.color = 'grey50', 
                           nudge_x = rep(c(-3,-3,-3,3,3,3),2),
                           hjust = rep(c(1,1,1,-1,-1,-1),2)); p

Example plot p

# Faceted plot with ggrepel (nudge_x and hjust assigned for each label)
# does not work when different number of variables in each facet

df1 <- df[-nrow(df),]; df1  # Remove one of the rows from df

# So this gives the following plot with different alluvia in each facet
p1 <- ggplot(df1, aes(y = value, axis1 = supplySector, axis2 = demandSector, group=region)) +
  ggalluvial::geom_alluvium(aes(fill = supplySector), width = 1/12, color="black", alpha=0.6) +
  ggalluvial::geom_stratum(width = 1/12, fill = "grey70", color = "grey10", alpha=1) +
  scale_x_discrete(limits = c("supplySector", "demandSector"), expand = c(0.3,0),drop=F) +
  facet_wrap(region~.); p1

Example plot with variable alluvia: p1

# If we try and label these and assigns the nudge and hjust for each axis we get an error
# It expects the same length vector for nudge and hjust for each facet
p1 + ggrepel::geom_text_repel(stat = "stratum", label.strata = TRUE, direction = "y", 
                              size = 4, segment.color = 'grey50',
                              nudge_x = rep(c(-3,-3,-3,3,3,3),2),
                              hjust=rep(c(1,1,1,-1,-1,-1),2))
# Gives error: Error: Aesthetics must be either length 1 or the same as the data (10): hjust

# If we adjust the vectors for nudge_x and hjust to 10
p1 + ggrepel::geom_text_repel(stat = "stratum", label.strata = TRUE, direction = "y", 
                              size = 4, segment.color = 'grey50',
                              nudge_x = c(-3,-3,-3,3,3,3,-3-3,3,3),
                              hjust = c(1,1,1,-1,-1,-1,1,1,-1,-1))

# Get Error: Error in data.frame(x = data$x + nudge_x, y = data$y + nudge_y) :
#           arguments imply differing number of rows: 9, 6
#           In addition: Warning message:
#           In data$x + nudge_x :
#           longer object length is not a multiple of shorter object length

# It can be plotted without specifying the nudge_x and hjust values
p1 + ggrepel::geom_text_repel(stat = "stratum", label.strata = TRUE, direction = "y", 
                              size = 4, segment.color = 'grey50')

Example plot with variable alluvia labels no repel: p1Norepel

Итак, я пытаюсь сделать следующее:

  • Для сюжета p1 (с разным количеством аллювии в разных гранях)
  • Маркируйте каждый столбец слоя оси x
  • метки оси1 отталкиваются влево и выравниваются по левому краю
  • Пусть метки оси2 отталкиваются вправо и выровнены по правому краю

В этом ответе предложена разная длина вектора для меток, но она не работает для разных граней. Маркировка и тема галлювиального сюжета в R

1 Ответ

0 голосов
/ 15 мая 2019

Это сложно!Аргументы nudge_* и *just обычно не являются динамическими.Один из способов, который вы могли бы решить для этого, - это копаться в кишках, используя ggplot_build()

ggplot_build() со всеми «инструкциями» о том, как ggplot() строит диаграмму.Вы можете отредактировать данные и затем запустить plot(ggplot_gtable()), чтобы увидеть график с вашими изменениями.Я добавил комментарии, чтобы помочь объяснить эти шаги.

# here is the base plot + the new layer for labels
plot_and_label <-
  p1 +
  geom_text_repel(
    stat = "stratum", label.strata = TRUE,
    direction = "y", size = 4,
    segment.color = 'grey50',
    nudge_x = 0
  )

# this is the plot under the hood
gg_guts <- ggplot_build(plot_and_label)

# the geom_text_repel layer was the 3rd one we added so you can 
# access and edit it like this
gg_guts$data[[3]] <-   
  gg_guts$data[[3]] %>%
  mutate(hjust = ifelse(x%%2 == 1, 2, -2))

# once you've made your adjustments, you can plot it again
plot(ggplot_gtable(gg_guts))

enter image description here

...