我有一个data.frame
,其中一个变量有多个级别(例如param1
,param2
和param3
)。所有这些水平都具有相同的单位(浓度mg L-1),但它们具有不同的数值范围。
例如
param1
的范围从0
到0.4
param2
的范围从0
到0.07
param3
的范围从0
到3000
我使用diamonds
创建了一个可重现的示例
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))
由于Fair
和Ideal
具有不同的值范围,因此我为Fair
和Ideal
创建了两个单独的图,以便能够在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)
顶部和底部图未沿x轴对齐。
我可以使用ggarrange()
包
egg
来解决此问题
library(egg)
f_1 <- ggarrange( f1, f2)
f_1
现在两个地块完全对齐。
问题
是否建议使用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线?
答案 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 = "")
如果您真的想要自定义中断,可以使用中断功能来提供这些:
{{1}}