library(tidyverse)
gapminder::gapminder %>%
filter(year == 2002) %>%
filter(continent == "Americas") ->
gap2002_americas_df
select_countries <- c("Chile" = "Chile", "United States" = "The US is here")
select_countries[as.character(gap2002_americas_df$country)]
## <NA> <NA> <NA> <NA>
## NA NA NA NA
## Chile <NA> <NA> <NA>
## "Chile" NA NA NA
## <NA> <NA> <NA> <NA>
## NA NA NA NA
## <NA> <NA> <NA> <NA>
## NA NA NA NA
## <NA> <NA> <NA> <NA>
## NA NA NA NA
## <NA> <NA> United States <NA>
## NA NA "The US is here" NA
## <NA>
## NA
i = 0
labs_tag_enumerate <- function(){
i <<- i + 1
# print(cat("Above code returns Plot", i - 1,"\n"))
return(labs(tag = paste("Plot", i - 1)))
}
Sometimes labels overlap the points, depending on the random numbers seed
library(tidyverse)
library(ggrepel)
gapminder::gapminder |>
filter(year == 2002) |>
ggplot() +
aes(gdpPercap, lifeExp) +
geom_point(colour = "darkgrey") ->
base_plot
aes_label_nas <- aes(label = select_countries[as.character(country)])
geom_text_repel_favs <- function(...){
geom_text_repel(na.rm = TRUE,
box.padding = unit(1, "cm"),
point.padding = unit(5, "mm"),
arrow = arrow(length = unit(2, "mm"),
type = "closed"), ...)
}
base_plot +
aes_label_nas +
geom_text_repel_favs() +
labs_tag_enumerate()
aes_label_empty_string <- aes(label = select_countries[as.character(country)] %>%
replace_na(""))
base_plot +
aes_label_empty_string + # New label
geom_text_repel_favs(
max.overlaps = 30 # overlaps
) +
labs_tag_enumerate()
base_plot +
aes_label_empty_string +
geom_text_repel_favs(
direction = "y", #<< direction y
max.overlaps = 30
) +
labs_tag_enumerate()
base_plot +
aes_label_empty_string +
geom_text_repel_favs(
nudge_y = 3, #<< New
direction = "y",
max.overlaps = 30
) +
labs_tag_enumerate()
base_plot +
aes_label_empty_string +
geom_text_repel_favs(
nudge_y = 4,
direction = "y",
force = 0,
force_pull = 0,
) +
labs_tag_enumerate()
In this case, the best approach seems to be the 4th: nudging + repulsion along y.
Tomorrow I should have a bit more time, and I will post here some variations using ‘ggpp’.
Hi.
Here are some examples with ‘ggpp’ and with ‘ggrepel’. I do not think any automatic approach can provide plots as nice as those than be obtained by manual placement. One important difference between ‘ggrepel’ and ‘ggpp’ is that geom_text_repel()
avoids clipping of labels at the edge of the plotting area, while geom_text_s()
behaves like geom_text()
and may clip part of labels. Of course, the solution is to manually expand the axis limits.
Padding ‘ggpp’ does not support ‘grid’ units, differemtly to ‘ggrepel’.
library(tidyverse)
library(ggpp)
library(ggrepel)
geom_text_s_favs <- function(...){
geom_text_s(
na.rm = TRUE,
box.padding = 0.5,
point.padding = 0.3,
arrow = arrow(length = unit(2, "mm"), type = "closed"), ...
)
}
# Using non-repulsive geom
base_plot +
aes_label_nas +
geom_text_s_favs(
nudge_y = 4
) +
labs_tag_enumerate()
base_plot +
aes_label_nas +
geom_text_s_favs(
aes(label = c("Chile" = "Chile", "United States" = "The US is here")[as.character(country)]),
nudge_y = 4, nudge_x = 1000,
hjust = "left"
) +
labs_tag_enumerate()
base_plot +
aes_label_nas +
geom_text_s_favs(
nudge_y = c(-4, 4), nudge_x = 1000,
hjust = "left",
) +
labs_tag_enumerate()
base_plot +
aes_label_nas +
geom_text_s_favs(
position = position_nudge_to(y = 82),
hjust = "left"
) +
labs_tag_enumerate()
some.countries <- c("Chile" = "Chile",
"Argentina" = "Argentina",
"Paraguay" = "Paraguay",
"Bolivia" = "Bolivia",
"Peru" = "Perú",
"Somalia" = "Somalia",
"United States" = "The US is here")
aes_label_some_countries <- aes(label = some.countries[as.character(country)])
base_plot +
geom_point(aes(alpha = country %in% names(some.countries)), show.legend = FALSE) ->
base_plot2
base_plot2 +
aes_label_some_countries +
geom_text_s_favs(
position = position_nudge_line(y = 4, x = 1000, method = "spline"),
hjust = "outward"
) +
labs_tag_enumerate()
base_plot2 +
aes_label_some_countries +
geom_text_s_favs(
position = position_nudge_line(y = 6, x =2500, method = "spline")
) +
labs_tag_enumerate()
base_plot2 +
aes_label_some_countries +
geom_text_s(
position = position_nudge_line(y = 6, x =2500, method = "spline"),
hjust = "outward"
) +
labs_tag_enumerate()
#> Warning: Using alpha for a discrete variable is not advised.
base_plot2 +
aes_label_some_countries +
geom_text_s(
position = position_nudge_line(y = 4, x = 1000, method = "spline",
direction = "split")
) +
labs_tag_enumerate()
The examples above tend to work, but there is no guarantee of no overlaps, so combining them with repulsion is safer. The more dispersion there is in the data points the more necessary repulsion becomes.
base_plot2 +
aes_label_some_countries +
geom_text_repel_favs(
position = position_nudge_line(y = 5, x = 3000, method = "spline"),
) +
labs_tag_enumerate()
The effect of justification is different in the geoms from ‘ggrepel’ and ‘ggpp’!
aes_label_some_countries_empty_string <- aes(label = ifelse(country %in% names(some.countries),
some.countries[as.character(country)],
""))
base_plot2 +
aes_label_some_countries_empty_string +
geom_text_repel(
position = position_nudge_line(y = 5, x = 3000, method = "spline"),
hjust = "outward", # <- added
na.rm = TRUE,
arrow = arrow(length = unit(2, "mm"), type = "closed"),
max.overlaps = 30
) +
labs_tag_enumerate()
base_plot2 +
aes_label_some_countries_empty_string +
geom_text_repel(
position = position_nudge_line(y = 5, x = 3000, method = "spline",
direction = "split"), # <-- added
hjust = "outward",
na.rm = TRUE,
max.overlaps = 50,
arrow = arrow(length = unit(2, "mm"), type = "closed")
) +
labs_tag_enumerate()
base_plot2 +
aes_label_some_countries_empty_string +
geom_text_repel(
position = position_nudge_line(y = 5, x = 3000, method = "spline",
direction = "automatic"), # <-- added
na.rm = TRUE,
max.overlaps = 50,
arrow = arrow(length = unit(2, "mm"), type = "closed")
) +
labs_tag_enumerate()
base_plot2 +
aes_label_some_countries_empty_string +
geom_text_repel(
position = position_nudge_line(y = 5, x = 3000, method = "spline",
direction = "automatic",
line_nudge = 1.5),
na.rm = TRUE,
max.overlaps = 50,
arrow = arrow(length = unit(2, "mm"), type = "closed")
) +
labs_tag_enumerate()
base_plot2 +
aes_label_some_countries_empty_string +
geom_text_repel(
position = position_nudge_line(y = 3, x = 2000, method = "spline",
direction = "split",
line_nudge = 2),
na.rm = TRUE,
max.overlaps = 50,
min.segment.length = 0,
arrow = arrow(length = unit(2, "mm"), type = "closed")
) +
labs_tag_enumerate()