ggplot:如何将常用的x和y标签添加到图的网格中 [英] ggplot: how to add common x and y labels to a grid of plots

查看:222
本文介绍了ggplot:如何将常用的x和y标签添加到图的网格中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用钻石,我想绘制克拉 vs 价格 4级( Fair ,好,很好 Premimum cut



不是让 facet_wrap()来控制坐标轴中的断点,而是用四个图来控制断点在轴上。

 库(ggplot2)
库(蛋)
库(网格)
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 =表达式(),
y =表达式())


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 ,价格))+
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(lim它= c(0,1000),break = c(0,200,400,600,800,1000))+
labs(x = expression(),
y = expression( ))

f4 < -
ggplot(diamonds [diamonds $ cut ==Premium,],aes(carat,price))+
geom_point()+ $ (限制= c(0,1.5),休息= c(0,0.2,0.4,0.6,0.8,1,1.2,1.4))+ b $ b facet_wrap(〜cut,ncol = 2)+
scale_x_continuous
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轴是s AME。唯一的区别是最小,最大和休息。我想为此图添加x和y标签。我可以在任何文档或图像编辑器中手动执行此操作。有没有办法直接在R中完成它?

解决方案

除了使用 gridExtra 包(根据@ user20650的建议),您还可以通过将钻石数据框分为 cut 并使用 mapply

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

 库(ggplot2)
库(gridExtra)
库(网格)
库)

删除 cut 理想

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

创建四张图,一个用于 cut 的每个剩余级别并存储在列表中。我们使用 mapply (而不是 lapply ),这样我们可以为<$ c的每个级别提供单独的数据框$ c> cut 和一个自定义 ymax 值的矢量,以分别为每个绘图设置y轴上的最高值。我们还添加了 color = clarity 以创建一个颜色图例:

  pl = mapply(FUN = function(df,ymax){
ggplot(df,aes(carat,price,color = clarity))+
geom_point()+
facet_wrap ,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( gr aphical ob 项目),然后从四个图中删除图例来完成此操作。



使用小帮助函数将图例解压为单独的grob:

 #提取图例的函数
#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< - 其中(sapply(tmp $ grobs,function(x)x $ name)==guide-box)
legend < - tmp $ grobs [[leg]]
return(legend)}

#将图例提取为grob
leg = g_legend(pl [[1]])

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

  grid.arrange(
arrangeGrob(grobs = lapply(pl,function(p)p + guides color = 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 )


Using diamonds, I want to plot carat vs price for 4 levels (Fair, Good, Very Good and Premimum) of cut.

Instead of allowing facet_wrap()to control the breaks in the axes, I made four plots to control the breaks in axes.

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   

RESULT

Each plot has a range of different y values

QUESTION

In all facets, x and y axes are the same. The only difference is the min, max and the breaks. I want to add x and y labels to this figure. I can do this manually in any word document or image editor. Is there anyway to do it in R directly?

解决方案

In addition to using functions from the gridExtra package (as suggested by @user20650), you can also create your plots with less code by splitting the diamonds data frame by levels of cut and using mapply.

The answer below also includes solutions for follow-up questions in the comments. We show how to lay out the four plots, add single x and y labels (including making them bold and controlling their color and size) that apply to all the plots, and get a single legend rather than a separate legend for each plot.

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

Remove rows where cut is "Ideal":

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

Create four plots, one for each remaining level of cut and store in a list. We use mapply (instead of lapply) so that we can provide both separate data frames for each level of cut and a vector of custom ymax values to set the highest value on the y-axis separately for each plot. We also add color=clarity in order to create a color legend:

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)

Okay, we have our four plots, but each one has its own legend. So now we want to arrange to have only one overall legend. We do this by extracting one of the legends as a separate grob (graphical object) and then removing the legends from the four plots.

Extract the legend as a separate grob using a small helper function:

# 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]])

Now we need to arrange the four plots in a 2x2 grid and then place the legend to the right of this grid. We use arrangeGrob to lay out the plots (and note how we use lapply to remove the legend from each plot before rendering it). This is essentially the same as what we did with grid.arrange in an earlier version of this answer, except that arrangeGrob creates the 2x2 plot grid object without drawing it. Then we lay out the legend beside the 2x2 plot grid by wrapping the whole thing inside grid.arrange. widths=c(9,1) allocates 90% of the horizontal space to the 2x2 grid of plots and 10% to the legend. Whew!

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)
)

这篇关于ggplot:如何将常用的x和y标签添加到图的网格中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆