ggplot:将图表对齐并添加常用标签和图例

时间:2016-08-18 06:10:46

标签: r ggplot2

我有一个data.frame,其中一个变量有多个级别(例如param1param2param3)。所有这些水平都具有相同的单位(浓度mg L-1),但它们具有不同的数值范围。

例如

param1的范围从00.4

param2的范围从00.07

param3的范围从03000

我使用diamonds创建了一个可重现的示例

,而不是使用我的data.frame
library(dplyr)
library(ggplot2)
df <- diamonds %>%
  dplyr::filter(cut%in%c("Fair","Ideal")) %>%
  dplyr::filter(clarity%in%c("I1" ,  "SI2" , "SI1" , "VS2" , "VS1",  "VVS2")) %>%
  dplyr::mutate(new_price = ifelse(cut == "Fair", 
                                   price/100000, 
                                   price/10))

由于FairIdeal具有不同的值范围,因此我为FairIdeal创建了两个单独的图,以便能够在y轴上分配断点

我希望两个图中的两个轴具有相同的小数位数。我使用了fmt_decimals() from here

library(dplyr)
library(ggplot2)
library(gridExtra)
library(grid)
#function to assign decimals for axes
fmt_dcimals <- function(decimals=0){
  function(x) format(x,nsmall = decimals,scientific = FALSE)
}


f1 <- 
 ggplot(df[df$cut == "Fair",], aes(x=carat , y= new_price, color = color))+
  geom_point(alpha = 0.3)+
  scale_y_continuous( limits = c(0,0.20), breaks=c(0, 0.05,0.1,0.15,0.2), labels = fmt_dcimals(2))+
  scale_x_continuous( limits = c(0,5.2), breaks=c(0,1,2,3,4,5), labels = fmt_dcimals(2))+
  facet_wrap(~cut) +
  labs(x = "",
       y = "")


f2 <- 
  ggplot(df[df$cut == "Ideal",], aes(x=carat , y= new_price, color = color))+
  geom_point(alpha = 0.3)+
  scale_y_continuous( limits = c(0,2000), breaks=c(0, 250,500,750,1000, 1250, 1500, 1750, 2000), labels = fmt_dcimals(2))+
  scale_x_continuous( limits = c(0,5.2), breaks=c(0,1,2,3,4,5), labels = fmt_dcimals(2))+
  facet_wrap(~cut) +
  labs(x = "",
       y = "")


f <- gridExtra::arrangeGrob(f1,f2, ncol=1, 
                            bottom=grid::textGrob(label= expression(Flow~(m^{3}~s^{-1})),
                                                  gp= gpar(fontsize=12, fontface="bold", col="black")),
                            left=grid::textGrob(label=expression(Concentration~mg~L^{-1}), rot=90, 
                                                gp= gpar(fontsize=12, fontface="bold", col="black")))

grid::grid.newpage() 
grid::grid.draw(f)

RESULT enter image description here

顶部和底部图未沿x轴对齐。

我可以使用ggarrange()

中的egg来解决此问题
library(egg)
f_1 <- ggarrange( f1, f2)
f_1

enter image description here

现在两个地块完全对齐。

问题

是否建议使用gridExtra沿x轴对齐两个图? 如果不 我可以使用egg添加轴的常用标签吗?

如何为这两个图添加一个图例

更新

感谢@ eipi10

我将其更新如下

library(cowplot)
# 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(f1)

# Remove legend from plots
f1 = f1 + theme(legend.position = "none")
f2 = f2 + theme(legend.position = "none")

# Lay out the two
f_1 = plot_grid(f1, f2, ncol =1, align="v")

f_3 <- grid.arrange(
  arrangeGrob(f_1,  
              bottom=grid::textGrob(label= expression(Flow~(m^{3}~s^{-1})),
                                    gp= gpar(fontsize=12, fontface="bold", col="black")),
              left=grid::textGrob(label=expression(Concentration~mg~L^{-1}), rot=90, 
                                  gp= gpar(fontsize=12, fontface="bold", col="black"))),
  leg, 
  widths=c(9,1))

但似乎使用cowplot,情节右侧没有垂直的y线?

enter image description here

1 个答案:

答案 0 :(得分:1)

我认为您只需使用ggplot(df[df$cut %in% c("Fair", "Ideal"),], aes(x=carat , y= new_price, color = color))+ geom_point(alpha = 0.3)+ scale_y_continuous(labels = fmt_dcimals(2))+ scale_x_continuous(limits = c(0,5.2), breaks=c(0,1,2,3,4,5), labels = fmt_dcimals(2))+ facet_wrap(~cut, scales = 'free_y', nrow = 2) + labs(x = "", y = "") 就能获得所需的一切,包括共享的x轴,共享的轴标题和适当的间距。对我来说,这似乎比搞乱gtables更容易。

这是一次非常好的尝试:

make_breaks <- function(ranges) {
  if(ranges[2] > 1) {
    c(0, 250,500,750,1000, 1250, 1500, 1750, 2000)
  } else {
    c(0, 0.05,0.1,0.15,0.2)
  }
}

ggplot(df[df$cut %in% c("Fair", "Ideal"),], aes(x=carat , y= new_price, color = color))+
  geom_point(alpha = 0.3)+
  scale_y_continuous(labels = fmt_dcimals(2), breaks = make_breaks)+
  scale_x_continuous(limits = c(0,5.2), breaks=c(0,1,2,3,4,5), labels = fmt_dcimals(2))+
  facet_wrap(~cut, scales = 'free_y', nrow = 2) +
  labs(x = "",
       y = "")

enter image description here

如果您真的想要自定义中断,可以使用中断功能来提供这些:

{{1}}

enter image description here