Connecting labels to points to avoid overlapping of labels

63 Views Asked by At

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")
}

0

There are 0 best solutions below