我花了很多时间尝试开发一个具有2个y轴的特定geom_bar图(双轴是工作要求)。
我已经让这些情节看起来可以接受了,除了条形宽度和条形放置有一些我不能解释/修复的不准确之处。
我意识到这很难看,但一些最大的问题如下:
(1)条宽变化。例如,在N2T_1面中,绿色条的宽度不同。我已经尝试在geom_bar中设置宽度,我发现它实际上是使用了一部分空间。我也尝试结合position_dodge调整宽度,这是我当前的代码。
(2)酒吧不在他们应该的位置。在N2U_2中,最高的绿色条形根据数据发生在1999年,但是当放大ggplot时,它出现在1998年,而2000年的价值出现在1999年。
(3)移动的条不会一直移动。在N2U_6中,最高的绿色条应该在2008年出现,但它出现在2009年的图表中。
我不确定我的代码是否出错,或者我是否遗漏了应该存在的内容。我很感激有关如何解决这些问题的任何建议。
当前代码:
# Left y-axis
p1 <- ggplot(data=DSCORE_CankDamage_N2, aes(x=Year, y=Dscore, group=Unique_ID_Tree))
p1 <- p1 + geom_rect(data=DSCORE_CankDamage_N2, aes(xmin=1965, xmax=1967, ymin=min(Dscore, na.rm=T), ymax=max(Dscore, na.rm=T)), alpha=0.1, fill="light goldenrod")
p1 <- p1 + geom_rect(data=DSCORE_CankDamage_N2, aes(xmin=1995, xmax=1997, ymin=min(Dscore, na.rm=T), ymax=max(Dscore, na.rm=T)), alpha=0.1, fill="light goldenrod")
p1 <- p1 + geom_rect(data=DSCORE_CankDamage_N2, aes(xmin=1999, xmax=2001, ymin=min(Dscore, na.rm=T), ymax=max(Dscore, na.rm=T)), alpha=0.1, fill="light goldenrod")
p1 <- p1 + geom_rect(data=DSCORE_CankDamage_N2, aes(xmin=2007, xmax=2009, ymin=min(Dscore, na.rm=T), ymax=max(Dscore, na.rm=T)), alpha=0.1, fill="light goldenrod")
p1 <- p1 + geom_hline(color="blue", linetype="dashed", aes(yintercept=0))
p1 <- p1 + geom_line(color="black")
p1 <- p1 + scale_x_continuous(limits=c(1945,2015), breaks=seq(1950,2010,10))
p1 <- p1 + ylab("Dscore")
p1 <- p1 + ggtitle("Annual Tree Decline (Dscore) and Total Canker Width (cm) per Year, Site N2")
p1 <- p1 + theme_bw() + theme(plot.margin=unit(c(1,1,1,1), "lines"),
plot.title=element_text(hjust=0.5, face="bold", family="Times New Roman", size=12, color="black"),
axis.title=element_text(size=12, family="Times New Roman", color="black"),
axis.text.y=element_text(size=10, family="Times New Roman", color="black"),
axis.text.x=element_text(size=10, family="Times New Roman", color="black", angle=90, vjust=0.5),
strip.text=element_text(size=9, family="Times New Roman"),
strip.background=element_rect(fill="azure2", colour="black",size=0.5),
strip.text.x=element_text(margin=margin(.1, 0, .1, 0, "cm")))
p1 <- p1 + facet_wrap(~Unique_ID_Tree, ncol=3, nrow=4)
# Right y-axis
p2 <- ggplot(data=DSCORE_CankDamage_N2, aes(x=Year, y=Cank_Width_cm))
p2 <- p2 + geom_bar(fill="darkgreen", alpha=0.6, width=0.6, position=position_dodge(width=0.9), stat="identity")
p2 <- p2 + facet_wrap(~Unique_ID_Tree, ncol=3, nrow=4)
p2 <- p2 + theme(plot.margin=unit(c(1,1,1,1), "lines"),
axis.title.y=element_text(size=12, color="black"),
axis.text=element_text(size=10, family="Times New Roman", color="black"),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
panel.background = element_rect(fill="transparent", colour = NA),
plot.background = element_rect(fill = "transparent", colour = NA))
# Combine left y-axis with right y-axis
p <- ggplot_dual_axis_facet(p1, p2)
grid.newpage()
png("DscoreWidthCankersClimate_N2.png", width=1000, height=600, units="px")
grid.draw(p)
grid.text("Width of Cankers (cm) per Year, per Tree", x=unit(0.95, "npc"), y=unit(0.5, "npc"), rot=90, gp=gpar(col="black", fontsize=12, fontfamily="Times New Roman"))
dev.off()
由another user from an earlier question开发的双轴功能:
#Plotting 2 axes, writing a dual axis plot function WITH FACET_WRAP!:
ggplot_dual_axis_facet <- function(p1, p2) {
#Extract gtable
library(gtable) # loads the grid package
g1 <- ggplot_gtable(ggplot_build(p1))
g2 <- ggplot_gtable(ggplot_build(p2))
#Overlap the panel of the 2nd plot on that of the 1st plot
pp <- c(subset(g1$layout, grepl("panel",name), se = t:r))
g <- gtable_add_grob(g1, g2$grobs[grep("panel",g2$layout$name)],
pp$t, pp$l, pp$b, pp$l)
#Tweak axis position and labels
ia <- which(grepl("axis_l",g2$layout$name) | grepl("axis-l",g2$layout$name))
ga <- g2$grobs[ia]
axis_idx <- as.numeric(which(sapply(ga,function(x) !is.null(x$children$axis))))
for(i in 1:length(axis_idx)){
ax <- ga[[axis_idx[i]]]$children$axis
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g2$widths[g2$layout[ia[axis_idx[i]], ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t[axis_idx[i]], length(g$widths) - i, pp$b[axis_idx[i]])
}
# Display plot with arrangeGrob wrapper arrangeGrob(g)
library(gridExtra)
grid.newpage()
return(arrangeGrob(g))
}
可重复的样品(减少到1990-2012,只有3个样品以节省空间):
DSCORE_CankDamage_N2 <- structure(list(Year = c(1990, 1990, 1990, 1991, 1991, 1991, 1992,
1992, 1992, 1993, 1993, 1993, 1994, 1994, 1994, 1995, 1995, 1995,
1996, 1996, 1996, 1997, 1997, 1997, 1998, 1998, 1998, 1999, 1999,
1999, 2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002, 2003,
2003, 2003, 2004, 2004, 2004, 2005, 2005, 2005, 2006, 2006, 2006,
2007, 2007, 2007, 2008, 2008, 2008, 2009, 2009, 2009, 2010, 2010,
2010, 2011, 2011, 2011, 2012, 2012, 2012), Unique_ID_Tree = c("N2T_1",
"N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2",
"N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6",
"N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1",
"N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2",
"N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6",
"N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1",
"N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2",
"N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6",
"N2T_1", "N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6", "N2T_1",
"N2U_2", "N2U_6", "N2T_1", "N2U_2", "N2U_6"), Dscore = c(-3.88097140918747,
-1.61672655331958, -0.800904163207618, -1.63987714337736, -1.27356679469661,
-0.123389213996389, -1.67470063459416, -1.53446926434865, 1.41432216204886,
-2.93976791454954, -2.22110579039093, 0.179787740964598, -0.496345860693154,
-2.25219836976259, 0.283128654684994, -1.02422222229106, -4.13093925848588,
-2.00025863911258, -1.42277115507557, -2.20286053942706, -1.59680054370485,
-4.67382100536604, -2.37506096226093, -2.8807566057491, -3.3382779475486,
-1.64425464849276, -3.27011139841957, -3.69418205392501, -2.786090370905,
-2.15312648161092, -2.03541950882678, -0.236513361147938, -1.080355218023,
-0.744061467812739, -0.51452406800711, -2.13834789020542, 1.28548134814991,
0.102783247605922, -8.60943620132279, 0.552638091261848, -2.6016685191023,
-2.00359494680614, 1.09364751195267, 0.0228740916470703, -0.727749095761693,
2.45361880473052, -0.700263607694208, 0.992436651274041, 5.55685390970607,
0.0126595727091467, -0.885094834004169, 0.286395340453474, -0.674875047272186,
-2.56290086784948, -1.6992770884242, 0.0858528219338089, -4.68307024987756,
-7.19053429537607, -0.688092915132032, -1.90683437925634, -3.31079202975985,
-2.00738870428399, -1.28966583325364, -1.35761860429989, -0.517228296926095,
-2.49977175344713, 0.558525687352873, 0.855141372994123, -1.00932485695081
), Cank_Width_cm = c(0, 0, 0.09398, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 2.90068, 0, 0, 0, 0, 0, 11.05916,
33.24606, 0.1397, 0.7112, 2.54508, 2.06248, 0, 0.4572, 3.11404,
0.86106, 0, 4.9784, 0, 0, 0, 0, 0, 0, 0, 3.27152, 0.09906, 0,
0.78994, 0, 0, 0, 0, 0, 0.61722, 29.5402, 0, 1.88722, 0, 0.08382,
2.43332, 0.25654, 0, 0.28956, 0, 0, 0.79756, 0), Canks_Per_Year = c(0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 3, 11, 1, 2, 3, 3, 0, 1, 4, 1, 0, 5, 0, 0, 0,
0, 0, 0, 0, 4, 1, 0, 1, 0, 0, 0, 0, 0, 2, 17, 0, 5, 0, 1, 6,
1, 0, 1, 0, 0, 2, 0)), .Names = c("Year", "Unique_ID_Tree", "Dscore",
"Cank_Width_cm", "Canks_Per_Year"), row.names = c(333L, 340L,
344L, 345L, 352L, 356L, 357L, 364L, 368L, 369L, 376L, 380L, 381L,
388L, 392L, 393L, 400L, 404L, 405L, 412L, 416L, 417L, 424L, 428L,
429L, 436L, 440L, 441L, 448L, 452L, 453L, 460L, 464L, 465L, 472L,
476L, 477L, 484L, 488L, 489L, 496L, 500L, 501L, 508L, 512L, 513L,
520L, 524L, 525L, 532L, 536L, 537L, 544L, 548L, 549L, 556L, 560L,
561L, 568L, 572L, 573L, 580L, 584L, 585L, 592L, 596L, 597L, 604L,
608L), class = "data.frame")