Connecting labels to points to avoid overlapping of labels Hi, I'm new to R and I feel frustrated, I've trying for couple of days now, but I think I need help, I'm trying plot a figure with different sizes and color data points, however; they are too close and overlap when labeled, so I tried to connect dispersed labels to their points with segments to avoid the overlap, but my figure looks ugly and the lines either horizontal or vertical, my labels are off too.
I'd like to use base R to solve it, but if there is no solution (or tedious) in base R, I'm open to any solution.
My data(head):
study year c p mc mp sc sp yi vi
1 1 2015 54 6 68.130 26.500 34.861 24.450 1.2053 0.1973
2 2 2007 26 8 23.000 18.400 13.000 8.200 0.3708 0.1655
3 3 2023 78 9 60.010 48.670 25.480 31.220 0.4311 0.1250
4 4 2013 69 9 53.400 24.700 37.700 25.700 0.7759 0.1295
5 5 2008 4 1 17.500 1.200 12.010 1.000 0.9821 1.3464
6 6 2015 40 8 132.075 25.875 38.697 23.648 2.8381 0.2339
where c (n) and p(n) are two groups, m(mean, s(STD), yi and vi is the output of another function.
The structure is:
Classes ‘escalc’ and 'data.frame': 18 obs. of 10 variables:
$ study: num 1 2 3 4 5 6 7 8 9 10 ...
$ year : num 2015 2007 2023 2013 2008 ...
$ c : num 54 26 78 69 4 40 38 88 7 24 ...
$ p : num 6 8 9 9 1 8 8 5 3 2 ...
$ mc : num 68.1 23 60 53.4 17.5 ...
$ mp : num 26.5 18.4 48.7 24.7 1.2 ...
$ sc : num 34.9 13 25.5 37.7 12 ...
$ sp : num 24.4 8.2 31.2 25.7 1 ...
$ yi : num 1.205 0.371 0.431 0.776 0.982 ...
..- attr(*, "ni")= num [1:18] 60 34 87 78 5 48 46 93 10 26 ...
..- attr(*, "slab")= chr [1:18] "1 2015" "2 2007" "3 2023" "4 2013" ...
..- attr(*, "measure")= chr "SMD"
$ vi : num 0.197 0.165 0.125 0.129 1.346 ...
- attr(*, "digits")= Named num [1:9] 4 4 4 4 4 4 4 4 4
..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ...
- attr(*, "yi.names")= chr "yi"
- attr(*, "vi.names")= chr "vi"
My code:
seeds_p <- escalc(measure = "SMD", m1i= mc , m2i= mp, sd1i= sc, sd2i= sp, n1i= c, n2i= p, data = seeds, slab = paste(study, year), drop00 = TRUE)
# Fit random-effects model using the DL estimator
res_p <- rma(yi, vi, data = seeds_p, method = "DL")
radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16,
cex = seeds_p$yi * 8 / max(seed_p$yi, na.rm = TRUE),
col = seeds$Col, cex.axis = 2, cex.lab = 1.8)
par(mar = c(7, 7, 7, 7) + 0.2) # Adjust the values as needed
# Extract only the study names without the date
study_labels <- gsub("\\s\\d{4}$", "", seeds$study)
# Add labels with basic text and segments
text_labels <- data.frame( x = res_p$yi * 4 / max(res_p$yi, na.rm = TRUE),
y = sqrt(1 / res_p$vi),
label = study_labels)
# Add labels with basic text
text(text_labels$x, text_labels$y, labels = text_labels$label, pos = 3, col = "black", cex = 0.8)
# Add segments connecting points to labels
segments(
x0 = text_labels$x,
y0 = text_labels$y,
x1 = res_p$yi * 15 / max(res_p$yi, na.rm = TRUE),
y1 = sqrt(1 / res_p$vi),
col = "black"
)
Results:
I've tried ggrepel and directlabels, I've also tried:
# Add labels and connecting lines
for (i in 1:nrow(seeds_p)) {
x <- res_p$yi[i] * 3 / max(res_p$yi, na.rm = TRUE)
y <- sqrt(1 / res_p$vi[i])
# Add label with offset
text(x, y, study_labels[i], pos = ifelse(x > 0, 4, 2), col = "black", offset = 1.5)
# Add connecting line
lines(c(x, x), c(y, 0), col = "black")
}
and I've tried:
# Create radial plot
radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16,
cex = seeds_p$yi * 3 / max(platelets_p$yi, na.rm = TRUE),
col = seeds$Col, cex.axis = 2, cex.lab = 1.8)
par(mar = c(7, 7, 7, 7) + 0.2) # Adjust the values as needed
# Extract only the study names without the date
study_labels <- gsub("\\s\\d{4}$", "", seeds_p$study)
# Add labels and connecting lines
for (i in 1:nrow(seeds_p)) {
x <- res_p$yi[i] * 3 / max(res_p$yi, na.rm = TRUE)
y <- sqrt(1 / res_p$vi[i])
# Add label
text(x, y, study_labels[i], pos = 3, col = "black")
# Add connecting line
lines(c(x, x), c(y, 0), col = "black")
}