Home > OS >  How to add multiple line caption where first line is centered and subsequent lines left-aligned?
How to add multiple line caption where first line is centered and subsequent lines left-aligned?

Time:11-26

I tried to add multiple line captions with the following conditions: first line should be centered and all the next lines must be aligned left. I tried the following codes but captions does not look as I planned like the following figure.

enter image description here

Is there any way to improve my code to present the caption as I intended?

ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species))   
  geom_point()    
  geom_line() 
  ylab("HHI")   
  labs(caption=expression(paste(italic("Source:"),"By author's calculation \n  Two extreme cases would have \n something blabla equal to 10,000 and 0, respectively.")))

CodePudding user response:

I think you will fair best (and with least headaches) when you use custom annotation, for each part of your caption separately. As a matter of fact, this type of solution helps with many, many problems - I think I am suggesting this in at least 50% of my answers to only seemingly very different issues... :D

More comments in the code.

library(ggplot2)

## I am typically defining x and y outside of ggplot in order to keep the code clearer -  
## x and y position very strongly depend on your final plot dimensions 
## and you will need to fine tune them depending on those
## the below is a semi-automatic approach
x_cap = mean(range(iris$Sepal.Length))
y_cap = min(iris$Sepal.Width)- .2*mean(range(iris$Sepal.Width ))
                     
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species))   
  geom_point()    
  geom_line() 
## I prefer annotating with annotate, if its only a single element
  annotate(geom = "text", x = x_cap, y = y_cap, 
           label = as.character(expression(paste(italic("Source:"),"By author's calculation"))),
           hjust = .5, parse = TRUE)  
  annotate(geom = "text", x = -Inf, y = y_cap-.2*y_cap, 
           label = "Two extreme cases would have \n something blabla equal to 10,000 and 0, respectively.",
           hjust = 0)  
  ## you need then to change your limits, and turn clipping off
  coord_cartesian(ylim = range(iris$Sepal.Width), clip = "off")  
  labs(y = "HHI")  
  ## you also need to adjust the plot margins
  theme(plot.margin = margin(.1, .1, 1, .1, unit = "inch"))

Created on 2021-11-25 by the reprex package (v2.0.1)

CodePudding user response:

This is just meant as a reference: A second option to achieve your desired result would be via the patchwork package which is my go-to-guy for almost everything (as is annotation_custom for @tjebo). Basically I add the second part of the caption via a "blank" caption plot which I glue to the main plot:

library(patchwork)
library(ggplot2)

p <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species))   
  geom_point()  
  geom_line()   
  ylab("HHI")  
  theme(plot.caption = ggtext::element_markdown(hjust = .5),
        plot.margin = margin(5.5, 5.5, 0, 5.5, "pt"))  
  labs(caption = "*Source:* By author's calculation")

p_caption <- ggplot(iris)  
  geom_blank()  
  theme_void()  
  theme(plot.caption =  element_text(hjust = 0, margin = margin(0, 0, 0, 0, "pt")),
        plot.margin = margin(0, 5.5, 5.5, 5.5, "pt"))  
  labs(caption = paste("Two extreme cases (monopoly and perfectly competitive market) would have", 
                       "an HHI equal to 10,000 and 0, respectively.",
                       "This figure shows that the market is not monopoly.", sep = "\n"))

p / p_caption   plot_layout(heights = c(40, 1))

  • Related