How to center a plot in window using ggplot2? (regardless of length of axis titles, legend, etc.)

时光怂恿深爱的人放手 提交于 2020-01-24 20:33:25

问题


[disambiguation: please note, I am not asking how to center the title, for which there are multiple answers already posted]

I am creating bar charts, using ggplot2 and one thing I have not been able to figure out is how to make the plot itself be centered in the window, regardless of length of vertical axis label text (which varies by data set), or the presence (or absence) of a legend to the right of the chart. I would like the square that contains the bar chart to always be in the center of my window. This is so that when I export it, all of the charts will sit in the center of slides in a presentation rather than being shifted to the left or the right based on text or other objects in the plot to either side of the bar chart.

For example, if there are very short vertical axis labels and no legend, the plot will be in center of window as I would like. But if I have a legend on the right, then it pushes my chart to the left. If I have long y-axis titles, it pushes my chart to the right. I don't want to use different legend positioning, for other reasons, so I am instead hoping to find a way to control the justification of the plot itself.

Thank you in advance for any suggestions!

Here's a sample of the code that generates the plot including some sample data:

chtit <- "Example"
l_labs <- c("","","")
x_labs <- c("imagine that you had a really long label here", 
            "and that the long labels move your chart over", 
            "and mess up the alignment")
ests <- c(.5,.3,.2)
nerrs <- c(.05, .05, .05)
perrs <- nerrs

barchart.data <- data.frame(l_labs, x_labs, ests, nerrs, perrs)

p<- ggplot(barchart.data, aes(x=x_labs, y=ests, fill=l_labs)) + 
geom_bar(stat="identity", color="#808080", position=position_dodge(), fill="#808080") +
geom_text(aes(y=ests+perrs+0.02, label=sprintf("%1.1f%%", 100*ests)), vjust=0.5, hjust=0, size=5, color="white") +
geom_errorbar(aes(ymin=ests-nerrs, ymax=ests+perrs), width=.2, position=position_dodge(.9), color="white", size=0.25) + 
labs(title=chtit, x= "", y = "Frequency") + theme_classic() + 
scale_y_continuous(limits = c(0,1.1), breaks=c(0, 0.2, 0.4, 0.6, 0.8, 1)) + 
theme(legend.position="none", legend.text = element_text(color = "white")) +
theme(title = element_text(colour = "white")) +
theme(axis.text = element_text(size=12, color = "white"), axis.line = element_line(color = "white")) +
theme(axis.title = element_text(size=12, color = "white")) +
coord_flip() +
theme(panel.grid.major.x = element_line(colour = "white",size=0.25)) +
theme(aspect.ratio = 1) +
theme(panel.background = element_rect(fill = "#1e1e1e")) +
theme(plot.background = element_rect(fill = "#1e1e1e"), plot.margin = unit(c(.5,.5,.5,.5), "in")) +
guides(fill = guide_legend(reverse = TRUE))
print(p)

回答1:


you can set the panel size,

library(egg)
set_panel_size(p, width= unit(6,"in"), height = unit(4,"in"), file = 'test.pdf')
set_panel_size(p + theme(axis.text.y = element_blank()), width= unit(6,"in"), height = unit(4,"in"), file = 'test2.pdf')

however the plot panel won't be centred on the device, that requires extra work. Here's one approach:

library(egg)
p2 <- p + theme(axis.text.y = element_blank())

g1 <- gtable_frame(ggplotGrob(p), width= unit(3,"in"), height = unit(2,"in"))
g2 <- gtable_frame(ggplotGrob(p2), width= unit(3,"in"), height = unit(2,"in"))


wrap <- function(g, fullwidth=unit(10, 'in')){

  ng <- grid::nullGrob()
  ag <- arrangeGrob(g, left=ng, right = ng)

  panel <- g$widths[2]
  margin <- 0.5*(fullwidth - panel)
  lw <- margin - g$widths[1]
  rw <- margin - g$widths[3]
  ag$widths[c(1,3)] <- unit.c(lw, rw)
  ag
}

pdf("compare.pdf", width=10, height=4, bg = 'black')
grid.draw(wrap(g1))
grid.newpage()
grid.draw(wrap(g2))
dev.off()



来源:https://stackoverflow.com/questions/46392661/how-to-center-a-plot-in-window-using-ggplot2-regardless-of-length-of-axis-titl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!