ggplot2 multiline title, different indentations

那年仲夏 提交于 2019-12-18 13:35:27

问题


I am generating graphs for a publication and I'd like to be able to label the panels of a figure in ggplot itself (as opposed to exporting to publisher, etc) so that they just fit neatly together in the final document. I was going to try to do this by adding a letter ("A") into the title, but I'd like my titles centered and I'd like the letter in the upper lefthand corner.

# base graph:

ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, shape = Species))+
  geom_jitter(size = 6.5)+
  ggtitle("A \n \n The Actual Long, Normal Title of Titliness")+
  theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 30),
        axis.ticks = element_blank(),
        legend.text = element_text(size = 25),
        axis.title = element_text(size = 25, face = "bold"),
        axis.text = element_text(size = 25, vjust = 0.05),
        legend.position = "bottom")

Now, if I'm willing to just "fake it" by hand-spacing each title, I can sort of get it to work, but this seems time intensive and crude.

# sloppy solution
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, shape = Species))+
  geom_jitter(size = 6.5)+
  ggtitle("A \n \n             The Actual Long, Normal Title of Titliness")+
  theme(plot.title = element_text(hjust = 0,face = "bold", size = 30),
        axis.ticks = element_blank(),
        legend.text = element_text(size = 25),
        axis.title = element_text(size = 25, face = "bold"),
        axis.text = element_text(size = 25, vjust = 0.05),
        legend.position = "bottom")

Is there a way to call each 'line' of the title individually for an hjust value of its own?

Any other creative solutions?

Also, I saw potential in mtext (Splitting axis labels with expressions), but couldn't figure out how to implement it with ggplot2 (vs base plot function.. it seems like they're not compatible). This post was all sorts of interesting (Multi-line ggplot Title With Different Font Size, Face, etc), but I am still new to R and I couldn't figure out how to edit this clever stuff to change indentation.

Thanks!


回答1:


Update: Since ggplot2 3.0.0 there is now native support for plot labels, see this answer.

Here is how I would do it, using the cowplot package that I wrote specifically for this purpose. Note that you get a clean theme as a bonus.

library(cowplot)

p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, shape = Species)) +
  geom_jitter(size = 3.5) +
  ggtitle("The Actual Long, Normal Title of Titliness")

# add one label to one plot
ggdraw(p) + draw_plot_label("A")

# place multiple plots into a grid, with labels
plot_grid(p, p, p, p, labels = "AUTO")

You then want to use the save_plot function to save plots instead of ggsave, because save_plot has defaults and parameters that help you get the scaling right relative to the theme, in particular for plots in a grid.




回答2:


Since ggplot2 3.0.0, there is a native way to do this, using the tag label:

ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, shape = Species)) +
  geom_point() +
  labs(title = "The Actual Long, Normal Title of Titliness",
       tag = "A")




回答3:


The easiest way is probably to use a title and a subtitle,

ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, shape = Species))+
  geom_jitter(size = 6.5) +
  labs(title = "A", subtitle = "The Actual Long, Normal Title of Titliness") +
  theme(plot.subtitle = element_text(hjust = 0.5))



回答4:


You can use grid.text from package grid, add text to your plot. Firstly add some space above your title use plot.margin.

library(grid)
p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, shape = Species))+
geom_jitter(size = 6.5)+
ggtitle("The Actual Long, Normal Title of Titliness")+
theme(plot.title = element_text(hjust = 0,face = "bold", size = 30),
      axis.ticks = element_blank(),
      legend.text = element_text(size = 25),
      axis.title = element_text(size = 25, face = "bold"),
      axis.text = element_text(size = 25, vjust = 0.05),
      legend.position = "bottom", 
      plot.margin = unit(c(4, 3, 1, 1), "lines"))
p
grid.text('A', x = unit(0.1, 'npc'), y = unit(.90, 'npc'), gp = gpar(fontsize=28))




回答5:


You can do this by manipulating Grobs. Using gtable and grid on top of ggplot2.

library("ggplot2")
library("gtable")
library("grid")

p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, shape = Species))+
  geom_jitter(size = 6.5)+
  ggtitle("The Actual Long, Normal Title of Titliness")+
  theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 30),
        axis.ticks = element_blank(),
        legend.text = element_text(size = 25),
        axis.title = element_text(size = 25, face = "bold"),
        axis.text = element_text(size = 25, vjust = 0.05),
        legend.position = "bottom",
        plot.margin = unit(c(4, 1, 1, 4), "lines"))  # We need bigger top/left margins to show the letter

gt <- ggplot_gtable(ggplot_build(p))  # Building a gtable from the ggplot object
# Adding the textGrob for the panel letter
panel_letter = textGrob("A", x = 0.5, y = .9, 
                        just = c("left", "top"), 
                        gp = gpar(fontsize = 40, col =  "black", face="bold"))
gt <- gtable_add_grob(gt, panel_letter, t=1, l=1, r=1)  # Append the Grob to the table

p <- grid.draw(gt)  # Display the plot
ggsave("plot.png",gt, width=10, height=10)  # If you want to save it.



来源:https://stackoverflow.com/questions/47523389/ggplot2-multiline-title-different-indentations

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