ggplot:如何将常见的x和y标签添加到绘图网格

shi*_*iny 3 r ggplot2

使用diamonds,我想绘制caratVS price为(4级FairGoodVery GoodPremimum的)cut

相反,允许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   
Run Code Online (Sandbox Code Playgroud)

结果

每个图都有一个不同的y值范围

在此处输入图片说明

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

eip*_*i10 6

除了使用gridExtra软件包中的功能(如@ user20650所建议)外,您还可以diamonds通过cut使用和划分数据框来用更少的代码创建绘图mapply

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

library(ggplot2)
library(gridExtra)
library(grid)
library(scales)
Run Code Online (Sandbox Code Playgroud)

删除行,其中cut"Ideal"

dat = diamonds[diamonds$cut != "Ideal",]
dat$cut = droplevels(dat$cut)
Run Code Online (Sandbox Code Playgroud)

创建四个图,每个剩余图一个,cut并存储在列表中。我们使用mapply(而不是lapply)来为每个级别的图提供单独的数据帧,cutymax为每个图提供分别在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)
Run Code Online (Sandbox Code Playgroud)

好的,我们有四个地块,但是每个地块都有自己的传说。因此,现在我们只希望安排一个整体图例。我们通过提取传说之一作为一个单独的格罗(这样做GR aphical OB JECT),然后取出从四个图表传说。

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

# 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]])
Run Code Online (Sandbox Code Playgroud)

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

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)
)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明