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.
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))