Related
How can I add an arrow next to the x and y axis titles, such as the picture below?
quadrant <- ggplot(quadrants, aes(x=Ampolla, y=Energia, label=Branca_percIPI))+
coord_fixed() +
coord_cartesian(clip = 'off') +
scale_x_continuous(expand = c(0, 0), limits = c(-5, 50)) +
scale_y_continuous(expand = c(0, 0), limits = c(0,50))+
geom_vline(xintercept = 11.3, color = "grey50", size=1.2) +
geom_hline(yintercept = 17.7, color = "grey50", size=1.2) +
geom_text_repel(size = 7,
colour = "#2896BA",
min.segment.length = Inf, hjust="right", nudge_x=0.9, nudge_y=1.5, force=1,
arrow = arrow(length=unit(0.5,"cm"), ends="first"), lineheight = 1)+
geom_point(colour="#2896BA", size=3.5)+
labs(title = "Incidència dels colls d'ampolla i dependència energètica total",
subtitle="(% de variació interanual de l'IPI*, % d'empreses afectades pels colls d'ampolla i % de dependència energètica)",
x = "Colls d'ampolla (% d'empreses afectades)**",
y = "Dependència energètica total (%)")+
annotation_custom(segmentsGrob(c(0.3, -0.1), c(-0.085, 0.28),
c(1, -0.1), c(-0.085, 0.28), gp = gpar(lwd = 2),
arrow = arrow(length = unit(2.5, 'mm'))))
You can turn clipping off inside coord_cartesian and add custom annotations for the arrows using segmentsGrob from the grid package inside annotation_custom:
library(ggplot2)
library(grid)
ggplot(iris, aes(Sepal.Length, Petal.Width)) +
geom_point(color = '#2896ba') +
geom_vline(xintercept = 5.5, color = 'gray50') +
geom_hline(yintercept = 0.8, color = 'gray50') +
coord_cartesian(clip = 'off') +
theme_minimal(base_size = 16) +
theme(axis.title = element_text(hjust = 0),
plot.caption = element_text(hjust = 0),
panel.grid = element_blank()) +
annotation_custom(segmentsGrob(c(0.3, -0.1), c(-0.085, 0.28),
c(1, -0.1), c(-0.085, 1), gp = gpar(lwd = 2),
arrow = arrow(length = unit(2.5, 'mm')))) +
labs(caption = paste0("Here is a very long caption to demonstrate that ",
"it is possible\nto add a very long caption ",
'underneath the x axis, thereby\n',
'emulating the caption in the plot in the question.'),
title = 'Another iris plot', subtitle = 'Just in case you need one')
I have a simple faceted plot from the following data
structure(list(Entity = c("Africa", "Americas", "Eastern Mediterranean",
"Europe", "South-East Asia", "Western Pacific"), meandeaths = c(93.9,
0.0821, 1.47, 0, 4.02, 0.569)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -6L))
I used the code here to add a single annotation at the bottom of the plot. Unfortunately, the annotation appears in each of the facets, although I have used inherit = TRUE in the aes.
library(ggfittext)
library(ggtext)
library(extrafont)
library(extrafontdb)
library(tidyverse)
plot_label <- 'Africa is the world region that is most affected by malaria: in 2019, 96% of global deaths from malaria occurred on the African continent.' %>%
str_wrap(width = 50)
colors_palette <- c(
"Africa"= "#01FF70",
"Americas" = "#FFDC00",
"Eastern Mediterranean" = "#FF851B",
"South-East Asia" = "#F012BE",
"Western Pacific" = "red",
"Europe" = "skyblue")
common_theme <- function() {
theme_minimal() +
theme(
text = element_text(color = "#FFFFFF"),
strip.text = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
panel.grid = element_blank(),
plot.title = element_markdown(family = "Century Gothic", size = rel(7.5), face = "bold", color = "#EF476F", hjust = .5, margin = margin(t = 1,b = 1, unit = "cm")),
plot.subtitle = element_markdown(size = rel(3), face = "bold", family = "Century Gothic", hjust = .5, margin = margin(t = .25, b = .25, unit = "cm")),
plot.background = element_rect(fill = "#111111", color = NA)
)
}
plotmal %>%
mutate(Entity = as.factor(Entity)) %>%
ggplot(aes(x = 3, fill = Entity)) +
geom_col(
aes(y= meandeaths),
color = NA
) +
geom_col(
aes(y = 1),
alpha = .35,
color = NA
) +
ggtext::geom_richtext(
aes(.2, 0,
label = glue::glue("<span style ='font-size: 35px;'>{str_to_title(Entity)}</span><br><span style='font-size:27.5px;'>{round(meandeaths,2)}%</span>"),
color = Entity
),
family = "Century Gothic",
fill = NA,
label.size = 0,
label.color = NA,
lineheight = 1.5
) +
annotate(geom ="text", x = 1.2, y =-1.5, label = plot_label,
size = 4.5, family = "Century Gothic" ,fontface = "italic", color = "#FFFFFF", lineheight = .95,inherit.aes = FALSE
)+ # inherit.aes = FALSE does not work
labs(
title = "Silent Killer",
subtitle = "Global Malaria Deaths by Region 2000-2020",
caption = "Data:OurWorldinData | Viz: #stepminer2"
) +
scale_x_continuous(
limits = c(0.2, 3 + 0.5)
) +
scale_fill_manual(
values = colors_palette,
guide = "none"
) +
scale_color_manual(
values = colors_palette,
guide = "none"
) +
coord_polar(theta = "y") +
facet_wrap(vars(Entity), nrow = 2) +
common_theme() +
theme(
plot.margin = margin(t = .5,b = 1, unit = "cm")
)
How can I solve this problem?
Unfortunately ggplot2::annotate or ggplot2::annotation_custom will add to each facet and using inherit=FALSE will not change that.
But one option to overcome this would be the gggrid package which unlike ggplot2::annotate or ggplot2::annotation_custom allows for placing different grobs on each facet or as in your case to place a label on only one facet. To this end:
Create your label as a textGrob which also allows to use relative coordinates to place your label.
Add this label to your plot via gggrid::grid_panel. Here you could pass a data.frame to the data argument which contains only an Entity column and which is used to specify the panels where you want to add the label, i.e. in your case "Europe".
tg <- grid::textGrob(plot_label,
x = unit(0, "npc") + unit(2, "mm"),
y = unit(0, "npc") + unit(2, "mm"),
just = c("left", "bottom"),
gp = grid::gpar(fontsize = 4.5 * .pt, fontfamily = "Century Gothic", col = "#FFFFFF", lineheight = .95)
)
plotmal %>%
mutate(Entity = as.factor(Entity)) %>%
ggplot(aes(x = 3, fill = Entity)) +
geom_col(
aes(y = meandeaths),
color = NA
) +
geom_col(
aes(y = 1),
alpha = .35,
color = NA
) +
ggtext::geom_richtext(
aes(.2, 0,
label = glue::glue("<span style ='font-size: 35px;'>{str_to_title(Entity)}</span><br><span style='font-size:27.5px;'>{round(meandeaths,2)}%</span>"),
color = Entity
),
family = "Century Gothic",
fill = NA,
label.size = 0,
label.color = NA,
lineheight = 1.5
) +
labs(
title = "Silent Killer",
subtitle = "Global Malaria Deaths by Region 2000-2020",
caption = "Data:OurWorldinData | Viz: #stepminer2"
) +
scale_x_continuous(
limits = c(0.2, 3 + 0.5)
) +
scale_fill_manual(
values = colors_palette,
guide = "none"
) +
scale_color_manual(
values = colors_palette,
guide = "none"
) +
coord_polar(theta = "y") +
facet_wrap(vars(Entity), nrow = 2) +
common_theme() +
theme(
plot.margin = margin(t = .5, b = 1, unit = "cm")
) +
gggrid::grid_panel(tg, data = data.frame(Entity = "Europe"))
UPDATE If you want your annotation to span the whole width of the plot I would go for a patchwork approach where the annotation is created as a second plot and glued to the main plot.
Note: For the annotation plot I use geom_textbox. I also dropped the str_wrap which IMHO does not make any sense in this case.
p_main <- plotmal %>%
mutate(Entity = as.factor(Entity)) %>%
ggplot(aes(x = 3, fill = Entity)) +
geom_col(
aes(y = meandeaths),
color = NA
) +
geom_col(
aes(y = 1),
alpha = .35,
color = NA
) +
ggtext::geom_richtext(
aes(.2, 0,
label = glue::glue("<span style ='font-size: 35px;'>{str_to_title(Entity)}</span><br><span style='font-size:27.5px;'>{round(meandeaths,2)}%</span>"),
color = Entity
),
family = "Century Gothic",
fill = NA,
label.size = 0,
label.color = NA,
lineheight = 1.5
) +
scale_fill_manual(
values = colors_palette,
guide = "none"
) +
scale_color_manual(
values = colors_palette,
guide = "none"
) +
coord_polar(theta = "y") +
facet_wrap(vars(Entity), nrow = 2) +
common_theme()
p_anno <- ggplot(data.frame(x = factor(1), y = factor(1)), aes(x = x, y = y)) +
geom_textbox(label = plot_label, color = "white", fill = "#111111", lineheight = .95,
family = "Century Gothic", size = 4.5, width = unit(1, "npc"), box.colour = NA,
halign = .5) +
common_theme() +
theme(
plot.margin = margin(t = .5, b = 1, unit = "cm")
)
library(patchwork)
p_main / p_anno + plot_layout(heights = c(20, 1)) &
plot_annotation(
title = "Silent Killer",
subtitle = "Global Malaria Deaths by Region 2000-2020",
caption = "Data:OurWorldinData | Viz: #stepminer2",
theme = common_theme()
)
I have This ggplot2 I made up to satisfy these conditions:
Remove default background that is hash colour to be plain.
Make (a) to be the plot title located within the plot area that is not close to the line (automatically).
Make $\phi = .8$ to be automatically at the head of the line (still within the plot area).
And sd = 1 to be automatically at the tail of the line.
The four(4) Borderlines to be present.
Gridlines to be a grey colour.
.
## simulate ARIMA(1, 0, 0)
set.seed(799837)
ts <- arima.sim(n = 10, model = list(ar = 0.95, order = c(1, 0, 0)), sd = 10)
gplot <- ggplot(NULL, aes(y = ts, x = seq_along(ts))) +
geom_line(color = "#F2AA4CFF") +
geom_point(color = "#101820FF") +
annotate("text", x = mean(seq_along(ts)), y = max(ts) * 1.1, label = "(a)")+
annotate("text", x = min(seq_along(ts)), y = max(ts) * 1.1, label = 'paste(~phi~"=.8")', parse = TRUE )+
annotate("text", x= max(seq_along(ts)), y = ts[[max(seq_along(ts))]] * 1.1, label = "sd=1") +
xlab('Time') +
ylab('Series') +
theme_bw() +
theme(axis.text = element_text(size = 40, angle = 0, vjust = 0.0, hjust = 0.0), #y-axis label size
axis.title = element_text(size = 40), #x-axis label size
axis.title.x = element_text(angle = 0, hjust = 0.5, vjust = 0.5, size = 40), # x-axis title
axis.title.y = element_text(angle = 90, hjust = 0.5, vjust = 0.5, size = 40), # y-axis title
plot.title = element_text(size = 40, margin = margin(t = 25, b = -20, l = 0, r = 0)),
panel.background = element_blank()) +
scale_x_continuous(breaks = seq(1,10,2)) +
scale_y_continuous(expand = c(0.0, 0.00))
gplot
I want the font of the plot title to increase. As you can see that despite setting the font of the plot title to 40 the font title refuse to increase. This question is a follow-up question from Remove Default Background Color and Make Title in Plot Zone
Daniel
If (a) is the 'title' it's not really the title, it's an annotation.
So to change it's size do it when you add the annotation.
annotate("text", x = mean(seq_along(ts)), y = max(ts) * 1.5, label = "(a)", size = 40)
You might also want to resize the other annotations.
annotate("text", x = mean(seq_along(ts)), y = max(ts) * 1.5, label = "(a)", size = 40) +
annotate("text", x = min(seq_along(ts)), y = max(ts) * 1.5, label = 'paste(~phi~"=.8")', parse = TRUE, size = 10)+
annotate("text", x= max(seq_along(ts)), y = ts[[max(seq_along(ts))]] * 1.5, label = "sd=1", size = 10)
I am trying to add images to a y-axis label. At the moment I am only able to add them inside the graph. You can find the code for the added images at the bottom of the code chunk. I want the flags to be displayed after or under or on top of the country name.
Does anybody know how to do it or where I can find a tutorial?
p <- ggplot(data, aes(x = country, y = thisyear)) +
geom_segment(aes(
x = reorder(country, thisyear) ,
xend = country,
y = lastyear,
yend = thisyear
),
color = "#3b3b3b") +
geom_point(size = 3, color = "#f7931b") +
geom_point(aes(x = country, y = lastyear), color = "#BCBCBC", size = 4) +
geom_point(aes(x = country, y = thisyear), color = "#f7931b", size = 4) +
annotate(
"text",
label = "this year",
x = nrow(data) - 0.7,
y = data[2, 3] + 3,
size = 4,
color = "#f7931b",
fontface = "bold"
) +
geom_curve(
aes(
x = nrow(data) - 0.85,
y = data[2, 3] + 3,
xend = nrow(data) - 1,
yend = data[2, 3] + 0.5
),
colour = "#f7931b",
size = 1,
curvature = -0.2,
arrow = arrow(length = unit(0.015, "npc"))
) +
annotate(
"text",
label = "last year",
x = nrow(data) - 1.5,
y = data[2, 2] + 3.2,
size = 4,
color = "#A8A8A8",
fontface = "bold"
) +
geom_curve(
aes(
x = nrow(data) - 1.35,
y = data[2, 2] + 3.2,
xend = nrow(data) - 1.05,
yend = data[2, 2] + 0.5
),
colour = "#A8A8A8",
size = 1,
curvature = -0.15,
arrow = arrow(length = unit(0.015, "npc"))
) +
scale_y_continuous(expand = expansion(mult = c(0, .05))) +
coord_flip() +
theme_ipsum() +
theme(
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank(),
legend.position = "none"
) +
labs(
title = "Share Of Global Bictoin Hashrate",
subtitle = paste0(as.character(format(maxdate, "%B %Y")), " Monthly Average"),
x = "",
y = '%',
caption = "#data99076083 | Source: Cambridge Centre for Alternative Finance (https://www.cbeci.org/mining_map)"
) +
theme_ipsum() +
theme(
legend.title = element_blank(),
plot.title = element_text(color = "#f7931b"),
plot.subtitle = element_text(color = "#3b3b3b"),
plot.caption = element_text(color = "#646464", face = 'bold'),
panel.border = element_rect(
colour = "grey",
fill = NA,
size = 1
)
)
p <-
p + geom_image(data = data, aes(x = id, y = 70, image = emoji), size = 0.04)
p
SOLUTION
As suggested I have tried to add the images with the [ggtext][2] tutorial. First I had to make the label vector with the HTML code:
labels <- c()
for (i in 1:length(data$emoji)){
img.name <- data$country[i]
labels <- c(labels, paste0("<img src='", data$emoji[i], "' width='25' /><br>*", img.name,"*"))
}
Example image code:
"<img src='../pics/twitter-emojis/flag-cote-divoire_1f1e8-1f1ee.png'
width='100' /><br>*I. virginica*"
After that the labels can be changed and printed with markdown:
p + scale_x_discrete(name = NULL,
labels = rev(labels)) +
theme(axis.text.y = element_markdown(color = "black", size = 11))
I'm trying to create a multiple plot with the same x-axis but different y-axes, because I have values for two groups with different ranges. As I want to control the values of the axes (respectively the y-axes shall reach from 2.000.000 to 4.000.000 and from 250.000 to 500.000), I don't get along with facet_grid with scales = "free".
So what I've tried is to create two plots (named "plots.treat" and "plot.control") and combine them with grid.arrange and arrangeGrob. My problem is, that I don't know how to control the exact position of the two plots, so that both y-axes are positioned on one vertical line. So in the example below the second plot's y-axis needs to be positioned a bit more to the right.
Here is the code:
# Load Packages
library(ggplot2)
library(grid)
library(gridExtra)
# Create Data
data.treat <- data.frame(seq(2005.5, 2015.5, 1), rep("SIFI", 11),
c(2230773, 2287162, 2326435, 2553602, 2829325, 3372657, 3512437,
3533884, 3519026, 3566553, 3527153))
colnames(data.treat) <- c("Jahr", "treatment",
"Aggregierte Depositen (in Tausend US$)")
data.control <- data.frame(seq(2005.5, 2015.5, 1), rep("Nicht-SIFI", 11),
c(324582, 345245, 364592, 360006, 363677, 384674, 369007,
343893, 333370, 318409, 313853))
colnames(data.control) <- c("Jahr", "treatment",
"Aggregierte Depositen (in Tausend US$)")
# Create Plot for data.treat
plot.treat <- ggplot() +
geom_line(data = data.treat,
aes(x = `Jahr`,
y = `Aggregierte Depositen (in Tausend US$)`),
size = 1,
linetype = "dashed") +
geom_point(data = data.treat,
aes(x = `Jahr`,
y = `Aggregierte Depositen (in Tausend US$)`),
fill = "white",
size = 2,
shape = 24) +
scale_x_continuous(breaks = seq(2005, 2015.5, 1),
minor_breaks = seq(2005, 2015.5, 0.5),
limits = c(2005, 2015.8),
expand = c(0.01, 0.01)) +
scale_y_continuous(breaks = seq(2000000, 4000000, 500000),
minor_breaks = seq(2000000, 4000000, 250000),
labels = c("2.000.000", "2.500.000", "3.000.000",
"3.500.000", "4.000.000"),
limits = c(2000000, 4000000),
expand = c(0, 0.01)) +
theme(text = element_text(family = "Times"),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.line.x = element_line(color="black", size = 0.6),
axis.line.y = element_line(color="black", size = 0.6),
legend.position = "none") +
geom_segment(aes(x = c(2008.7068),
y = c(2000000),
xend = c(2008.7068),
yend = c(3750000)),
linetype = "dotted") +
annotate(geom = "text", x = 2008.7068, y = 3875000, label = "Lehman\nBrothers + TARP",
colour = "black", size = 3, family = "Times") +
geom_segment(aes(x = c(2010.5507),
y = c(2000000),
xend = c(2010.5507),
yend = c(3750000)),
linetype = "dotted") +
annotate(geom = "text", x = 2010.5507, y = 3875000, label = "Dodd-Frank-\nAct",
colour = "black", size = 3, family = "Times") +
geom_rect(aes(xmin = 2007.6027, xmax = 2009.5, ymin = -Inf, ymax = Inf),
fill="dark grey", alpha = 0.2)
# Create Plot for data.control
plot.control <- ggplot() +
geom_line(data = data.control,
aes(x = `Jahr`,
y = `Aggregierte Depositen (in Tausend US$)`),
size = 1,
linetype = "solid") +
geom_point(data = data.control,
aes(x = `Jahr`,
y = `Aggregierte Depositen (in Tausend US$)`),
fill = "white",
size = 2,
shape = 21) +
scale_x_continuous(breaks = seq(2005, 2015.5, 1), # x-Achse
minor_breaks = seq(2005, 2015.5, 0.5),
limits = c(2005, 2015.8),
expand = c(0.01, 0.01)) +
scale_y_continuous(breaks = seq(250000, 500000, 50000),
minor_breaks = seq(250000, 500000, 25000),
labels = c("250.000", "300.000", "350.000", "400.000",
"450.000", "500.000"),
limits = c(250000, 500000),
expand = c(0, 0.01)) +
theme(text = element_text(family = "Times"),
axis.title.x = element_blank(), # Achse
axis.title.y = element_blank(), # Achse
axis.line.x = element_line(color="black", size = 0.6),
axis.line.y = element_line(color="black", size = 0.6),
legend.position = "none") +
geom_segment(aes(x = c(2008.7068),
y = c(250000),
xend = c(2008.7068),
yend = c(468750)),
linetype = "dotted") +
annotate(geom = "text", x = 2008.7068, y = 484375, label = "Lehman\nBrothers + TARP",
colour = "black", size = 3, family = "Times") +
geom_segment(aes(x = c(2010.5507),
y = c(250000),
xend = c(2010.5507),
yend = c(468750)),
linetype = "dotted") +
annotate(geom = "text", x = 2010.5507, y = 484375, label = "Dodd-Frank-\nAct",
colour = "black", size = 3, family = "Times") +
geom_rect(aes(xmin = 2007.6027, xmax = 2009.5, ymin = -Inf, ymax = Inf),
fill="dark grey", alpha = 0.2)
# Combine both Plots with grid.arrange
grid.arrange(arrangeGrob(plot.treat, plot.control,
ncol = 1,
left = textGrob("Aggregierte Depositen (in Tausend US$)",
rot = 90,
vjust = 1,
gp = gpar(fontfamily = "Times",
size = 12,
colout = "black",
fontface = "bold")),
bottom = textGrob("Jahr",
vjust = 0.1,
hjust = 0.2,
gp = gpar(fontfamily = "Times",
size = 12,
colout = "black",
fontface = "bold"))))
Do:
install.packages("cowplot")
but do not library(cowplot) as it'll mess up your theme work.
Then, do:
grid.arrange(
arrangeGrob(cowplot::plot_grid(plot.treat, plot.control, align = "v", ncol=1),
ncol = 1,
left = textGrob("Aggregierte Depositen (in Tausend US$)",
rot = 90,
vjust = 1,
gp = gpar(fontfamily = "Times",
size = 12,
colout = "black",
fontface = "bold")),
bottom = textGrob("Jahr",
vjust = 0.1,
hjust = 0.2,
gp = gpar(fontfamily = "Times",
size = 12,
colout = "black",
fontface = "bold"))))