首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用共享轴在图形中排列面板

用共享轴在图形中排列面板
EN

Stack Overflow用户
提问于 2020-06-03 18:23:19
回答 1查看 155关注 0票数 3

我正试着用三个面板来做一个图形。我想删除轴标题和文本,无论哪两个面板相邻(见下面的例子),并将一个图例放置在空的方面。

面板A和B应该有一个相同的y轴,所有三个面板都有相同的x轴(A和B基本上是完整数据集和子集的图,而C表示百分比变化)。我在这里看到了很多关于堆栈溢出的有用的帖子,但是没有人确切地解释了我想知道的事情。

我尝试: 1)用facet_wrap()将面板绘制为面,使用element_blank()控制轴限值(如解释的here),并使用this函数替换图例:

代码语言:javascript
复制
# function to replace legend
library(lemon)

shift_legend2 <- function(p) {
  # ...
  # to grob
  gp <- ggplotGrob(p)
  facet.panels <- grep("^panel", gp[["layout"]][["name"]])
  empty.facet.panels <- sapply(facet.panels, function(i) "zeroGrob" %in% class(gp[["grobs"]][[i]]))
  empty.facet.panels <- facet.panels[empty.facet.panels]

  # establish name of empty panels
  empty.facet.panels <- gp[["layout"]][empty.facet.panels, ]
  names <- empty.facet.panels$name
  # example of names:
  #[1] "panel-3-2" "panel-3-3"

  # now we just need a simple call to reposition the legend
  reposition_legend(p, 'center', panel=names)
}

# add dummy data for element_blank()
dat <- dat %>%
  mutate(y_min = ifelse(figure == "pct_change", 0.8, 0),
         y_max = ifelse(figure == "pct_change", 1.6, 150))

# plot
plot1 <- ggplot(dat, aes(x = year, y = values)) + 
  geom_line(aes(col = class)) +
  theme_cowplot(12) +
  facet_wrap(~figure, nrow = 2, scales = "free_y") +
  geom_blank(aes(y = y_min)) +
  geom_blank(aes(y = y_max))

# rearrange legend
shift_legend2(plot1)

( 2)将地块分开,然后再安排。

代码语言:javascript
复制
a <- ggplot(dat[dat$figure == "d_complete",], aes(x = year, y = values)) + 
  geom_line(aes(col = class)) +
  theme_cowplot(12) +
  theme(legend.position = "none",
                      axis.title.x = element_blank(),
                      axis.text.x = element_blank())

b <- ggplot(dat[dat$figure == "d_subset",], aes(x = year, y = values)) + 
  geom_line(aes(col = class)) +
  theme_cowplot(12) + 
  theme(legend.position = "none",
                     axis.title.y = element_blank(),
                     axis.text.y = element_blank()) +
  ylim(c(0, 120)

c <- ggplot(dat[dat$figure == "pct_change",], aes(x = year, y = values)) + 
  geom_line(aes(col = class)) +
  theme_cowplot(12) +
  theme(legend.position = "none")

plot2 <- plot_grid(a, b, c, ncol=2, align = "hv", axis = "bl")

以下是研究结果:

现在的问题是:

  • 在图1中,面板A的x轴线消失了,我不能为面板A和C放置不同的y轴图例,而B面板的y轴文本仍然在图2中的
  • 中,图之间有非常丑陋的空白,我不知道如何添加传奇

谢谢你的帮忙!

数据:

代码语言:javascript
复制
dput(dat)
structure(list(class = c("AUN", "AUN", "AUN", "AUN", "AUN", "AUN", 
"AUN", "AUN", "AUN", "CHE", "CHE", "CHE", "CHE", "CHE", "CHE", 
"CHE", "CHE", "CHE"), year = c(0L, 0L, 0L, 5L, 5L, 5L, 10L, 10L, 
10L, 0L, 0L, 0L, 5L, 5L, 5L, 10L, 10L, 10L), figure = c("d_subset", 
"d_complete", "pct_change", "d_subset", "d_complete", "pct_change", 
"d_subset", "d_complete", "pct_change", "d_subset", "d_complete", 
"pct_change", "d_subset", "d_complete", "pct_change", "d_subset", 
"d_complete", "pct_change"), values = c(73, 99, 1, 84, 118, 1.19191919191919, 
80, 96, 0.96969696969697, 12, 16, 1, 19, 27, 1.6875, 16, 20, 
1.25), y_min = c(0, 0, 0.8, 0, 0, 0.8, 0, 0, 0.8, 0, 0, 0.8, 
0, 0, 0.8, 0, 0, 0.8), y_max = c(150, 150, 1.6, 150, 150, 1.6, 
150, 150, 1.6, 150, 150, 1.6, 150, 150, 1.6, 150, 150, 1.6)), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -18L), groups = structure(list(
    class = c("AUN", "CHE"), .rows = list(1:9, 10:18)), row.names = c(NA, 
-2L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-03 20:48:43

我认为你在第二个选择中非常接近。您只需要修改a、b和c图的plot.margin,以减少可怕的空白的大小,然后使用ggdraw将图例添加为grob。下面是生成所需情节的完整代码。

代码语言:javascript
复制
library(tidyverse)
library(cowplot)

# Your original plots with the corresponding plot.margin
# Set the bottom margin to 0 to decrease the vertical gap between a and c plots
a <- ggplot(dat[dat$figure == "d_complete",], aes(x = year, y = values)) + 
   geom_line(aes(col = class)) +
   theme_cowplot(12) +
   theme(legend.position = "none",
         axis.title.x = element_blank(),
         axis.text.x = element_blank(),
         # modify the plot's margins: top, right, bottom, left
         plot.margin = unit(c(0.2,0,0,0), "cm"))

# Use same margins as plot a
b <- ggplot(dat[dat$figure == "d_subset",], aes(x = year, y = values)) + 
   geom_line(aes(col = class)) +
   theme_cowplot(12) + 
   theme(legend.position = "none",
         axis.title.y = element_blank(),
         axis.text.y = element_blank(),
         # modify the plot's margins: top, right, bottom, left
         plot.margin = unit(c(0.2,0,0,0), "cm")) +
   ylim(c(0, 120))

# Set top margin to -0.7 to decrease the vertical gap (between a and c)        
c <- ggplot(dat[dat$figure == "pct_change",], aes(x = year, y = values)) + 
      geom_line(aes(col = class)) +
      theme_cowplot(12) +
      theme(legend.position = "none",
            # modify the plot's margins: top, right, bottom, left
            plot.margin = unit(c(-0.7,0,0.2,0), "cm"))

# Construct the c plot with legend
temp_plot <- dat %>%
   filter(figure == "pct_change") %>%
   ggplot(aes(x = year, y = values)) + 
   geom_line(aes(col = class))

# get the plot's legend and transform it to a grob
legend <- as_grob(get_legend(temp_plot))

# Put a, b and c plots together
plot2 <- plot_grid(a, b, c, ncol=2, align = "hv", axis = "bl")

# Add the legend
plot3 <- ggdraw(plot2) +
   # set x and y position to draw the legend, usually requires playing with values between -1 and 1
   draw_grob(legend, x = 0.25, y = 0.05, width = 1, height = 0.5)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62180033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档