问题
[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