简体   繁体   English

在多面冲积图中可变对齐ggrepel文本标签

[英]Variable align ggrepel text labels in faceted alluvial plot

I am trying to create a faceted alluvial plot with labels for the stratums on the first axis repelled to the left and left justified and the labels on the right repelled to the right and right justified. 我正在尝试创建一个刻面的冲积图,第一个轴上的层被标记为左和左对齐,右边的标签被排斥到右和右对齐。

# 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

示例图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

带有变量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')

带有变量alluvia标签的示例图没有排斥:p1Norepel

In summary, what I am trying to do is: 总之,我想要做的是:

  • For plot p1 (with different number of alluvia in different facets) 对于情节p1(在不同方面具有不同数量的alluvia)
  • Label each x axis stratum column 标记每个x轴的stratum列
  • Have axis1 labels repel to the left and be left justified 让axis1标签向左排斥并左对齐
  • Have axis2 labels repel to the right and be right justified 让axis2标签向右排斥并且右对齐

This answer suggested the different vector length for labels but it doesn't work for varying facets. 这个答案提出了标签的不同矢量长度,但它不适用于不同的方面。 Labelling and theme of ggalluvial plot in R R中ggalluvial图的标记和主题

This is tricky! 这很棘手! The nudge_* and *just arguments generally aren't dynamic. nudge_**just参数通常不是动态的。 One way you could solve for this is to dig into the guts using ggplot_build() 你可以解决这个问题的一种方法是使用ggplot_build()挖掘内脏

ggplot_build() has all of the "instructions" of how ggplot() builds the chart. ggplot_build()拥有所有的如何的“指令” ggplot()构建图表。 You can edit the data and then run plot(ggplot_gtable()) to see the plot with your modifications. 您可以编辑数据,然后运行plot(ggplot_gtable())以查看包含修改的图。 I have added comments to help explain these steps. 我添加了评论以帮助解释这些步骤。

# 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))

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM