[英]how to set dual Y axis in geom_bar plot in ggplot2?
I'd like to draw bar plot like this but in dual Y axis我想像这样画条 plot 但在双 Y 轴上
( https://i.stack.imgur.com/ldMx0.jpg ) ( https://i.stack.imgur.com/ldMx0.jpg )
the first three indexs range from 0 to 1, so I want the left y-axis (corresponding to NSE, KGE, VE) to range from 0 to 1, and the right y-axis (corresponding to PBIAS) to range from -15 to 5.前三个索引的范围是0到1,所以我希望左边的y轴(对应NSE、KGE、VE)的范围是0到1,右边的y轴(对应PBIAS)的范围是-15到 5。
the following is my data and code:以下是我的数据和代码:
library("ggplot2")
## data
data <- data.frame(
value=c(0.82,0.87,0.65,-3.39,0.75,0.82,0.63,1.14,0.85,0.87,0.67,-7.03),
sd=c(0.003,0.047,0.006,4.8,0.003,0.028,0.006,4.77,0.004,0.057,0.014,4.85),
index=c("NSE","KGE","VE","PBIAS","NSE","KGE","VE","PBIAS","NSE","KGE","VE","PBIAS"),
period=c("all","all","all","all","calibration","calibration","calibration","calibration","validation","validation","validation","validation")
)
## fix index sequence
data$index <- factor(data$index, levels = c('NSE','KGE','VE',"PBIAS"))
data$period <- factor(data$period, levels = c('all','calibration', 'validation'))
## bar plot
ggplot(data, aes(x=index, y=value, fill=period))+
geom_bar(position="dodge", stat="identity")+
geom_errorbar(aes(ymin=value-sd, ymax=value+sd),
position = position_dodge(0.9), width=0.2 ,alpha=0.5, size=1)+
theme_bw()
I try to scale and shift the second y-axis, but PBIAS bar plot was removed because of out of scale limit as follow:我尝试缩放和移动第二个 y 轴,但 PBIAS 条 plot 由于超出比例限制而被删除,如下所示:
( https://i.stack.imgur.com/n6Jfm.jpg ) ( https://i.stack.imgur.com/n6Jfm.jpg )
the following is my code with dual y axis:以下是我的双 y 轴代码:
## bar plot (scale and shift the second y-axis with slope/intercept in 20/-15)
ggplot(data, aes(x=index, y=value, fill=period))+
geom_bar(position="dodge", stat="identity")+
geom_errorbar(aes(ymin=value-sd, ymax=value+sd),
position = position_dodge(0.9), width=0.2 ,alpha=0.5, size=1)+
theme_bw()+
scale_y_continuous(limits = c(0,1), name = "value", sec.axis = sec_axis(~ 20*.- 15, name="value"))
Any advice for move bar_plot or other solution?对移动 bar_plot 或其他解决方案有什么建议吗?
Taking a different approach, instead of using a dual axis one option would be to make two separate plots and glue them together using patchwork
.采用不同的方法,而不是使用双轴,一种选择是制作两个单独的图并使用
patchwork
将它们粘合在一起。 IMHO that is much easier than fiddling around with the rescaling the data (that's the step you missed, ie if you want to have a secondary axis you also have to rescale the data) and makes it clearer that the indices are measured on a different scale:恕我直言,这比摆弄重新缩放数据要容易得多(这是你错过的步骤,即如果你想要一个辅助轴,你还必须重新缩放数据)并且更清楚地表明指数是在不同的尺度上测量的:
library(ggplot2)
library(patchwork)
data$facet <- data$index %in% "PBIAS"
plot_fun <- function(.data) {
ggplot(.data, aes(x = index, y = value, fill = period)) +
geom_bar(position = "dodge", stat = "identity") +
geom_errorbar(aes(ymin = value - sd, ymax = value + sd),
position = position_dodge(0.9), width = 0.2, alpha = 0.5, size = 1
) +
theme_bw()
}
p1 <- subset(data, !facet) |> plot_fun() + scale_y_continuous(limits = c(0, 1))
p2 <- subset(data, facet) |> plot_fun() + scale_y_continuous(limits = c(-15, 15), position = "right")
p1 + p2 +
plot_layout(guides = "collect", width = c(3, 1))
A second but similar option would be to use ggh4x
which via ggh4x::facetted_pos_scales
allows to set the limits for facet panels individually.第二个但类似的选项是使用
ggh4x
,它通过ggh4x::facetted_pos_scales
允许单独设置分面面板的限制。 One drawback, the panels have the same width.一个缺点是面板具有相同的宽度。 (I failed in making this approach work with
facet_grid
and space="free"
) (我未能使这种方法适用于
facet_grid
和space="free"
)
library(ggplot2)
library(ggh4x)
data$facet <- data$index %in% "PBIAS"
ggplot(data, aes(x = index, y = value, fill = period)) +
geom_bar(position = "dodge", stat = "identity") +
geom_errorbar(aes(ymin = value - sd, ymax = value + sd),
position = position_dodge(0.9), width = 0.2, alpha = 0.5, size = 1
) +
facet_wrap(~facet, scales = "free") +
facetted_pos_scales(
y = list(
facet ~ scale_y_continuous(limits = c(-15, 15), position = "right"),
!facet ~ scale_y_continuous(limits = c(0, 1), position = "left")
)
) +
theme_bw() +
theme(strip.text.x = element_blank())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.