【问题标题】:ggplot: how to add common x and y labels to a grid of plotsggplot:如何将常见的 x 和 y 标签添加到绘图网格中
【发布时间】:2016-08-18 01:50:55
【问题描述】:

使用diamonds,我想为cut 的4 个级别(FairGoodVery GoodPremimum)绘制caratprice

我没有让facet_wrap()控制坐标轴的中断,而是制作了四个图来控制坐标轴的中断。

library(ggplot2)
library(egg)
library(grid)
f1 <- 
ggplot(diamonds[diamonds$cut=="Fair",], aes(carat, price))+
  geom_point()+
  facet_wrap(~cut, ncol =2)+
  scale_x_continuous(limits = c(0,4), breaks=c(0,  1, 2, 3, 4))+
  scale_y_continuous(limits = c(0,10000), breaks=c(0,  2500, 5000, 7500, 10000))+
  labs(x=expression(" "),
       y=expression(" "))


f2 <- 
ggplot(diamonds[diamonds$cut=="Good",], aes(carat, price))+
  geom_point()+
  facet_wrap(~cut, ncol =2)+
  scale_y_continuous(limits = c(0,5000), breaks=c(0,  1000, 2000, 3000, 4000, 5000))+
  labs(x=expression(" "),
       y=expression(" "))


f3 <- 
  ggplot(diamonds[diamonds$cut=="Very Good",], aes(carat, price))+
  geom_point()+
  facet_wrap(~cut, ncol =2)+
  scale_x_continuous(limits = c(0,1), breaks=c(0, 0.2,  0.4, 0.6, 0.8, 1))+
  scale_y_continuous(limits = c(0,1000), breaks=c(0,  200, 400, 600, 800, 1000))+
  labs(x=expression(" "),
       y=expression(" "))

f4 <- 
  ggplot(diamonds[diamonds$cut=="Premium",], aes(carat, price))+
  geom_point()+
  facet_wrap(~cut, ncol =2)+
  scale_x_continuous(limits = c(0,1.5), breaks=c(0, 0.2,  0.4, 0.6, 0.8, 1, 1.2, 1.4))+
  scale_y_continuous(limits = c(0, 3000), breaks=c(0,  500, 1000, 1500, 2000, 2500, 3000))+
  labs(x=expression(" "),
       y=expression(" "))

fin_fig <- ggarrange(f1, f2, f3, f4, ncol =2)
fin_fig   

结果

每个图都有一系列不同的 y 值

问题

在所有方面,x 和 y 轴都是相同的。唯一的区别是最小值、最大值和休息时间。我想在这个图中添加 x 和 y 标签。我可以在任何 Word 文档或图像编辑器中手动执行此操作。反正有没有直接在R中做?

【问题讨论】:

  • 看看grid::textGrobggplot2::annotation_custom
  • 您可以使用gridExtra,它具有leftbottom 参数。 :p &lt;- ggplot() ; g &lt;- gridExtra::arrangeGrob(p,p,p,p,ncol=2, bottom=grid::textGrob("bottom lab"), left=grid::textGrob("left lab", rot=90)) ; grid::grid.newpage() ; grid::grid.draw(g)

标签: r ggplot2


【解决方案1】:

除了使用gridExtra 包中的函数(如@user20650 所建议的那样),您还可以通过将diamonds 数据框按cut 的级别拆分并使用mapply 来使用更少的代码创建绘图.

下面的答案还包括 cmets 中后续问题的解决方案。我们展示了如何布置四个图,添加适用于所有图的单个 x 和 y 标签(包括使它们变粗并控制它们的颜色和大小),并为每个图获取单个图例而不是单独的图例。

library(ggplot2)
library(gridExtra)
library(grid)
library(scales)

删除cut"Ideal" 的行:

dat = diamonds[diamonds$cut != "Ideal",]
dat$cut = droplevels(dat$cut)

创建四个图,每个剩余级别一个cut 并存储在一个列表中。我们使用mapply(而不是lapply),以便我们可以为cut 的每个级别提供单独的数据框和自定义ymax 值的向量,以分别为每个级别设置y 轴上的最大值阴谋。我们还添加color=clarity 以创建颜色图例:

pl = mapply(FUN = function(df, ymax) {
  ggplot(df, aes(carat, price, color=clarity))+
    geom_point()+
    facet_wrap(~cut, ncol=2)+
    scale_x_continuous(limits = c(0,4), breaks=0:4)+
    scale_y_continuous(limits = c(0, ymax), labels=dollar_format()) +
    labs(x=expression(" "),
         y=expression(" "))
}, df=split(dat, dat$cut), ymax=c(1e4,5e3,1e3,3e3), SIMPLIFY=FALSE)

好的,我们有四个情节,但每个情节都有自己的传奇。所以现在我们要安排只有一个整体图例。为此,我们将其中一个图例提取为单独的 grob(graphical objectject),然后从四个图中删除图例。

使用一个小的辅助函数将图例提取为单独的 grob:

# Function to extract legend
# https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot){
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend) }

# Extract legend as a grob
leg = g_legend(pl[[1]])

现在我们需要将四个图排列在一个 2x2 的网格中,然后将图例放置在该网格的右侧。我们使用arrangeGrob 来布置绘图(并注意我们如何使用lapply 在渲染之前从每个绘图中删除图例)。这与我们在此答案的早期版本中对 grid.arrange 所做的基本相同,除了 arrangeGrob 创建 2x2 绘图网格对象而不绘制它。然后我们通过将整个东西包裹在grid.arrange 中,在 2x2 绘图网格旁边布置图例。 widths=c(9,1) 将 90% 的水平空间分配给 2x2 网格图,10% 分配给图例。呼!

grid.arrange(
  arrangeGrob(grobs=lapply(pl, function(p) p + guides(colour=FALSE)), ncol=2, 
              bottom=textGrob("Carat", gp=gpar(fontface="bold", col="red", fontsize=15)), 
              left=textGrob("Price", gp=gpar(fontface="bold", col="blue", fontsize=15), rot=90)),
  leg, 
  widths=c(9,1)
)

【讨论】:

  • 感谢您的时间和帮助。请检查更新以查看我无法使用“更少代码”的原因。我不得不制作四个不同的图,因为它们都有不同的 y 和 x 值范围,但它们仍然具有相同的单位。
  • 查看更新。我已更改为mapply,以便我们可以包含一个参数来分别为每个绘图设置 y 轴的顶部。
  • 感谢您的时间和帮助。有什么建议如何更改标签的大小和面(加粗)?
  • 查看更新的代码。我还输入了颜色和字体大小,以防万一。
  • 查看更新的代码。我添加了一种颜色美学来获得一个图例,并展示了如何用一个图例来布置情节。
猜你喜欢
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
相关资源
最近更新 更多