如何在ggplot中控制Facet_wrap中的垂直空间

How to control vertical spaces in Facet_wrap in ggplot

我创建了一个跨评级和地理两个维度的分面图 (Geo_class)。如何在不同地理 classes (panel.spacing.x) 之间引入 space,同时避免在评级 classes 之间引入 space。此处示例数据 https://www.dropbox.com/s/n3tbiexbvpuqm3t/Final_impact_melt_All5.csv?dl=0

下图中1到3、4、5、6、7代表Ratings,Geo_Class是(Saudi Arabia, NOn GCC, Other GCC and All)。方法是新的还是旧的。 我使用以下代码生成图

p<-ggplot(Final_impact_melt_All5, aes(x=Method, y=Capital_Charge, fill= Capital_Charge_type))+ geom_bar(stat='Identity', width= 1)
p + facet_wrap (Geo_class ~ Ratings, nrow = 2) + scale_fill_brewer(palette ="Oranges") + theme(axis.text=element_text(size=6),panel.spacing.x=unit(0, "lines"),panel.spacing.y=unit(1, "lines"))

我喜欢的是将图表分成 4 个面板(Geo_class 每个面板一个,即沙特阿拉伯、其他海湾合作委员会、非海湾合作委员会和所有)。我想将评级之间的间距保持为零,这样就呈现出集群堆叠条形图的外观。

另一个好处是,如果我可以多次摆脱地理 class 的重复,它只在 4 个新面板的每个面板上显示一次。

这是你想要的吗?据我所知,仅使用 ggplot 无法完成您的要求。下面的代码并不漂亮。这取决于 gtablegrid 函数。它分解 ggplot 图中的条带,然后以适当的间距构造新的条带。该代码适用于示例中内部和外部条带标签的特定配置。如果发生变化,代码就会中断。它可能无法在下一个版本的 ggplot 中存活下来。

library(ggplot2)
library(grid)
library(gtable)

# Set spacing between Geo_class and between Ratings
OuterSpacing = unit(5, "pt") # spacing between Geo_class
InnerSpacing = unit(0, "pt") # spacing between Ratings

# Your ggplot
p <- ggplot(Final_impact_melt_All5, 
           aes(x=Method, y=Capital_Charge, fill= Capital_Charge_type)) + 
    geom_bar(stat='Identity', width= 1)
plot = p + 
   facet_wrap (Geo_class ~ Ratings, nrow = 2) + 
    scale_fill_brewer(palette ="Oranges") + 
    theme(axis.text=element_text(size=6), 
          panel.spacing.x = OuterSpacing,
          panel.spacing.y = unit(1, "lines"))


# Get the ggplot grob
g = ggplotGrob(plot)

# Set spacing between 'Ratings' to 'InnerSpacing'
g$widths[c(seq(6, by=4, length.out=4), seq(26, by=4, length.out=4)) ] = InnerSpacing

# Get a list of strips
strip = lapply(grep("strip-t", g$layout$name), function(x) {g$grobs[[x]]})

# Number of strips
URow = 4;  LRow = 5   # Top row and Bottom row

# Construct gtable to contain the new strip
Inner = (rep(unit.c(unit(1, "null"), InnerSpacing), LRow))[-10]

newStrip  = gtable(widths = (rep(unit.c(Inner, OuterSpacing), URow))[-40], 
                   heights = strip[[1]]$heights)

## Populate the gtable 
# Top Row
cols1 = seq(1, by = 5, length.out = 4)
cols2 = (seq(1, by = 10, length.out = 4))
newStrip = gtable_add_grob(newStrip,  lapply(strip[cols1], `[`, 1), t = 1, l = cols2, r = cols2 + 8)

# Bottom row
cols = seq(1, by = 2, length.out = 20)
newStrip = gtable_add_grob(newStrip, lapply(strip, `[`, 2), t = 2, l = cols)

## Add the strips to the plot, 
# making sure the second half go in the upper section (t=6)
# and the first half go in the lower section (t=11)
pgNew = gtable_add_grob(g, newStrip[1:2, 21:39], t = 6, l = 4, r = 40)
pgNew = gtable_add_grob(pgNew, newStrip[1:2, 1:19], t = 11, l = 4, r = 40)

# Remove the original strip
for(i in 102:121) pgNew$grobs[[i]] = nullGrob()


# Draw the plot
grid.newpage()
grid.draw(pgNew)