在所有的facet_wrap中添加x轴和y轴。

44

在绘图时,通常希望最小化墨水的使用。我有一个面板图(facet_wrap),希望尽可能地减少墨水的使用,但仍保持可读性。我已经设置好了,除非在最左边或底部,否则子图中没有 x 轴和 y 轴。由于删除了这么多墨水,我认为眼睛需要这些线索,并询问如何将 x 轴和 y 轴放入 facet_wrap 中的所有图中。以下是我的代码,当前输出和期望的输出(红线是期望添加的):

library(ggplot); library(grid)

ggplot(mtcars, aes(mpg, hp)) + 
    geom_point() + 
    facet_wrap(~carb) +
    theme(panel.grid = element_blank(),
        panel.background = element_rect(fill = "white", colour = "black"), 
        panel.border = element_rect(fill = NA, colour = "white"), 
        axis.line = element_line(),
        strip.background = element_blank(),
        panel.margin = unit(2, "lines"))

现有情节 enter image description here

期望情节 enter image description here


@Thomas,不好意思。让我补充一下所使用的库。 - Tyler Rinker
你不能轻松地这样做,因为除非scales = "free",否则每个面板上都不会显示axis.line主题元素,而panel.border主题元素是一个矩形,并且您无法为矩形元素的不同侧指定不同的值。你可以使用geom_vlinegeom_hline来伪造它,但很难使其看起来正确。 - Ista
你可以从@baptiste在这里和这里的回答中获取一些想法。 - Henrik
gridExtra::borderGrob(type=9) 可以帮助解决问题,如果 ggplot2 允许在主题元素中有一定的灵活性 - baptiste
@baptise,你能恢复你的答案吗? - Tyler Rinker
显示剩余2条评论
6个回答

46

这将显着简化事情:

library('ggthemes')
ggplot(mtcars, aes(mpg, hp)) + geom_point() + facet_wrap(~carb, scales='free') + 
    theme_tufte() + theme(axis.line=element_line()) + 
    scale_x_continuous(limits=c(10,35)) + scale_y_continuous(limits=c(0,400))

在这里输入图片描述


1
最简单的答案是,对我来说,“scales = free”不好。+1 - Tyler Rinker
1
@TylerRinker 看到了编辑。没注意到你把所有东西都限制在相同的比例尺上。 - Thomas
1
这个答案不适用于最新的ggplot2版本2.2.1。 - wikiselev
1
@wikiselev 对我来说可行,使用的是ggplot2_2.2.1和ggthemes_3.4.0。 - Thomas
@Thomas 好的,那是因为 ggthemes 的缘故吗?ggplot 本身不能工作吗? - wikiselev
这个解决方案适用于日期吗?比如 scale_x_date(limits= ?) - Julien

38

最简单的方法是在每个绘图面板中添加分段。

ggplot(mtcars, aes(mpg, hp)) + 
  geom_point() + 
  facet_wrap(~carb) +
  theme_minimal() +
  annotate("segment", x=-Inf, xend=Inf, y=-Inf, yend=-Inf)+
  annotate("segment", x=-Inf, xend=-Inf, y=-Inf, yend=Inf)

example


对我来说,这导致额外行的宽度不同,非常令人烦恼... - JelenaČuklina
1
我希望对我的图表也使用这个简单的答案,但是我的x轴使用日期,这会导致错误:“错误:无效输入:date_trans仅适用于Date类的对象”。有什么想法吗? - Tingolfin
@JelenaČuklina 尝试添加一个 size 参数,例如 annotate("segment", x=-Inf, xend=Inf, y=-Inf, yend=-Inf, size = 1) +。这对我有用。 - Øystein S

19

根据以上 Thomas 的回答 -

你只需要在 facet_wrap 中设置 scales='free',并确保在 scale_x_continuousscale_y_continuous 中设置限制。

ggplot(mtcars, aes(mpg, hp)) + geom_point() + facet_wrap(~carb, scales='free') + 
    scale_x_continuous(limits=c(10,35)) + scale_y_continuous(limits=c(0,400))

16

lemon包添加了此功能;请参阅此文献。(示例代码和图形来自该文献。)

library(lemon)
p + facet_rep_grid(drv ~ cyl) + coord_capped_cart(bottom='both', left='both') +
  theme_bw() + theme(panel.border=element_blank(), axis.line=element_line())

来自柠檬文档:


5

我自己找到了一个简单的解决方案——可以在ggh4x软件包中找到此功能,使用方法为facet_wrap2(~carb, axes="all", remove_labels="all")

library(ggplot2)
library(ggh4x)

ggplot(mtcars, aes(mpg, hp)) + 
    geom_point() + 
    facet_wrap2(~carb, axes = "all", remove_labels = "all") + # this can also just by "x" or "y" to remove axis labels
    theme(panel.grid = element_blank(),
        panel.background = element_rect(fill = "white", colour = "black"), 
        panel.border = element_rect(fill = NA, colour = "white"), 
        axis.line = element_line(),
        strip.background = element_blank(),
        panel.margin = unit(2, "lines"))

enter image description here


4

这里有一个冗长的解决方法。

首先,将原始绘图存储为对象,然后创建另一个没有轴标记和轴文本的绘图。

p1<-ggplot(mtcars, aes(mpg, hp)) + 
  geom_point() + 
  facet_wrap(~carb) +
  theme(panel.grid = element_blank(),
        panel.background = element_blank(), 
        panel.border = element_blank(), 
        axis.line = element_line(),
        strip.background = element_blank(),
        panel.margin = unit(2, "lines"))

p2<-ggplot(mtcars, aes(mpg, hp)) + 
  geom_point() + 
  facet_wrap(~carb) +
  theme(panel.grid = element_blank(),
        panel.background = element_blank(), 
        panel.border = element_blank(), 
        axis.line = element_line(),
        strip.background = element_blank(),
        panel.margin = unit(2, "lines"),
        axis.ticks=element_blank(),
        axis.text=element_blank())

现在使用函数ggplotGrob()将这两个图表转换为grobs。如果我们查看这些grobs的结构,您会发现可见的y轴是grob 14和17(其他是零grobs),而x轴是grob 23到25。

g1<-ggplotGrob(p1)
g2<-ggplotGrob(p2)
g2
TableGrob (12 x 12) "layout": 28 grobs
    z         cells       name                                     grob
1   0 ( 1-12, 1-12) background          rect[plot.background.rect.3481]
2   1 ( 4- 4, 4- 4)    panel-1                gTree[panel-1.gTree.3356]
3   2 ( 4- 4, 7- 7)    panel-2                gTree[panel-2.gTree.3366]
4   3 ( 4- 4,10-10)    panel-3                gTree[panel-3.gTree.3376]
5   4 ( 8- 8, 4- 4)    panel-4                gTree[panel-4.gTree.3386]
6   5 ( 8- 8, 7- 7)    panel-5                gTree[panel-5.gTree.3396]
7   6 ( 8- 8,10-10)    panel-6                gTree[panel-6.gTree.3406]
8   7 ( 3- 3, 4- 4)  strip_t-1    absoluteGrob[strip.absoluteGrob.3448]
9   8 ( 3- 3, 7- 7)  strip_t-2    absoluteGrob[strip.absoluteGrob.3453]
10  9 ( 3- 3,10-10)  strip_t-3    absoluteGrob[strip.absoluteGrob.3458]
11 10 ( 7- 7, 4- 4)  strip_t-4    absoluteGrob[strip.absoluteGrob.3463]
12 11 ( 7- 7, 7- 7)  strip_t-5    absoluteGrob[strip.absoluteGrob.3468]
13 12 ( 7- 7,10-10)  strip_t-6    absoluteGrob[strip.absoluteGrob.3473]
14 13 ( 4- 4, 3- 3)   axis_l-1 absoluteGrob[axis-l-1.absoluteGrob.3433]
15 14 ( 4- 4, 6- 6)   axis_l-2         zeroGrob[axis-l-2.zeroGrob.3434]
16 15 ( 4- 4, 9- 9)   axis_l-3         zeroGrob[axis-l-3.zeroGrob.3435]
17 16 ( 8- 8, 3- 3)   axis_l-4 absoluteGrob[axis-l-4.absoluteGrob.3441]
18 17 ( 8- 8, 6- 6)   axis_l-5         zeroGrob[axis-l-5.zeroGrob.3442]
19 18 ( 8- 8, 9- 9)   axis_l-6         zeroGrob[axis-l-6.zeroGrob.3443]
20 19 ( 5- 5, 4- 4)   axis_b-1         zeroGrob[axis-b-1.zeroGrob.3407]
21 20 ( 5- 5, 7- 7)   axis_b-2         zeroGrob[axis-b-2.zeroGrob.3408]
22 21 ( 5- 5,10-10)   axis_b-3         zeroGrob[axis-b-3.zeroGrob.3409]
23 22 ( 9- 9, 4- 4)   axis_b-4 absoluteGrob[axis-b-4.absoluteGrob.3415]
24 23 ( 9- 9, 7- 7)   axis_b-5 absoluteGrob[axis-b-5.absoluteGrob.3421]
25 24 ( 9- 9,10-10)   axis_b-6 absoluteGrob[axis-b-6.absoluteGrob.3427]
26 25 (11-11, 4-10)       xlab             text[axis.title.x.text.3475]
27 26 ( 4- 8, 2- 2)       ylab             text[axis.title.y.text.3477]
28 27 ( 2- 2, 4-10)      title               text[plot.title.text.3479]

因此,使用图2相应的grobs替换图1中的零grobs,您将获得轴线。
g1[[1]][[15]]<-g2[[1]][[14]]
g1[[1]][[16]]<-g2[[1]][[14]]
g1[[1]][[18]]<-g2[[1]][[14]]
g1[[1]][[19]]<-g2[[1]][[14]]
g1[[1]][[20]]<-g2[[1]][[23]]
g1[[1]][[21]]<-g2[[1]][[23]]
g1[[1]][[22]]<-g2[[1]][[23]]

grid.draw(g1)

enter image description here


为什么不直接向gtable的每个面板添加段落呢? - baptiste
@baptiste 因为我不知道如何做到那一点。欢迎您展示一下。 - Didzis Elferts
工作得很好,但我看到 baptise 提供了一个更具普适性的答案,但他已经删除了。+1 - Tyler Rinker
@TylerRinker 是的,Baptiste的答案更好。 - Didzis Elferts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接