Overlapping labels in ggplot2

Viewed 449

I have the following plot:

There are two overlaping labels and I do not know how to do to show both of them without one being on top of the other one. My code is:

ggplot(data = tic,
       aes(x = tic,
           y = Promedio,
           fill = rural)) +
  geom_point(aes(shape = tipo),
             size = 2,
             alpha = 0.7) +
  scale_shape_manual(values = c("Departamental" = 22,
                                "Distrital" = 21,
                                "Municipal" = 23),
                     name = "Tipo de SE") +
  theme_minimal() +
  theme(
    legend.position = c(0.19,0.83),
    legend.background = element_rect(fill=rgb(1,1,1), 
                                     size=0.5, 
                                     linetype="solid"),
    legend.box = "horizontal",
    legend.title = element_text(size=13 )
  ) + geom_hline(yintercept = 250,
                 linetype = "dashed") +
  geom_vline(xintercept = 91,
             linetype = "dashed") +
  ylab("Promedio del puntaje global del Examen Saber 11° 2016-2019") +
  xlab("Porcentaje de establecimientos educativos con TIC") +
  scale_fill_gradient(name = "Ruralidad",
                      low = "green",
                      high = "red") +
  geom_label(data = tic[tic$etc=="CALDAS",],
             aes(y = Promedio,
                 label = "Caldas",
                 fontface = "bold"),
             size = 3) +
  geom_label(data = tic[tic$etc=="RISARALDA",],
             aes(y = Promedio,
                 label = "Risaralda",
                 fontface = "bold"),
             size = 3) +
  geom_label(data = tic[tic$etc=="PEREIRA",],
             aes(y = Promedio,
                 label = "Pereira"),
             size = 3,
             fontface = "bold") +
  geom_label(data = tic[tic$etc=="ARMENIA",],
             aes(y = Promedio,
                 label = "Armenia"),
             size = 3,
             fontface = "bold") +
  geom_label(data = tic[tic$etc=="QUINDÍO",],
             aes(y = Promedio,
                 label = "Quindío"),
             size = 3,
             fontface = "bold") +
  labs(caption = "Nota: Las líneas punteadas corresponden a las medianas de las correspondientes variables")

I tried by giving them some angle using the angle argument in geom_label() but it did not work. Does anyone know how I can solve this?

My data can me reproducible by:

structure(list(etc = c("AMAZONAS", "ANTIOQUIA", "APARTADÓ", "ARAUCA", 
"ARMENIA", "ATLÁNTICO", "BARRANCABERMEJA", "BARRANQUILLA", "BELLO", 
"BOGOTÁ, D.C.", "BOLÍVAR", "BOYACÁ", "BUCARAMANGA", "BUENAVENTURA", 
"BUGA", "CALDAS", "CALI", "CAQUETÁ", "CARTAGENA", "CARTAGO", 
"CASANARE", "CAUCA", "CESAR", "CHÍA", "CHOCÓ", "CIÉNAGA", "CÓRDOBA", 
"CÚCUTA", "CUNDINAMARCA", "DOSQUEBRADAS", "DUITAMA", "ENVIGADO", 
"FACATATIVÁ", "FLORENCIA", "FLORIDABLANCA", "FUSAGASUGÁ", "GIRARDOT", 
"GIRÓN", "GUAINÍA", "GUAVIARE", "HUILA", "IBAGUÉ", "IPIALES", 
"ITAGÜÍ", "JAMUNDÍ", "LA GUAJIRA", "LORICA", "MAGANGUÉ", "MAGDALENA", 
"MAICAO", "MALAMBO", "MANIZALES", "MEDELLÍN", "META", "MONTERÍA", 
"MOSQUERA", "NARIÑO", "NEIVA", "NORTE DE SANTANDER", "PALMIRA", 
"PASTO", "PEREIRA", "PIEDECUESTA", "PITALITO", "POPAYÁN", "PUTUMAYO", 
"QUIBDÓ", "QUINDÍO", "RIOHACHA", "RIONEGRO", "RISARALDA", "SABANETA", 
"SAHAGÚN", "SAN ANDRÉS", "SANTA MARTA", "SANTANDER", "SINCELEJO", 
"SOACHA", "SOGAMOSO", "SOLEDAD", "SUCRE", "TOLIMA", "TULUÁ", 
"TUMACO", "TUNJA", "TURBO", "URIBIA", "VALLE DEL CAUCA", "VALLEDUPAR", 
"VAUPÉS", "VICHADA", "VILLAVICENCIO", "YOPAL", "YUMBO", "ZIPAQUIRÁ"
), tic = c(77.5, 77.4579783559751, 63.013698630137, 81.335952848723, 
96.3302752293578, 96.113074204947, 91.0994764397906, 95.0909090909091, 
89.5161290322581, 96.3756177924217, 81.0593900481541, 92.1052631578947, 
97.2602739726027, 82.1727019498607, 91.2280701754386, 90.8333333333333, 
92.0477137176938, 78.7625418060201, 94.2184154175589, 95.7142857142857, 
92.3076923076923, 83.2853025936599, 77.3056057866184, 92.9292929292929, 
33.5483870967742, 72.4550898203593, 79.8767967145791, 96.037296037296, 
92.0209059233449, 88.8111888111888, 85.1851851851852, 90.6976744186046, 
94.5054945054945, 77.5510204081633, 97.5609756097561, 94.1747572815534, 
93.9024390243902, 93.75, 77.3584905660377, 76.056338028169, 95.1333333333333, 
94.7780678851175, 90.8256880733945, 94.1860465116279, 90.3508771929825, 
35.0553505535055, 91.6129032258064, 89.5238095238095, 74.7357293868922, 
48.8584474885845, 92.7536231884058, 95.7345971563981, 95.4486345903771, 
76.2303664921466, 81.8452380952381, 98.2142857142857, 77.3294908741595, 
92.5675675675676, 85.6265984654732, 94.2222222222222, 95.1807228915663, 
93.4169278996865, 89.5161290322581, 98.9417989417989, 93.5622317596567, 
69.1897654584222, 57.5, 98.2517482517483, 66.6666666666667, 96.6101694915254, 
85.546218487395, 96.6666666666667, 96.4912280701754, 91.1764705882353, 
91.1357340720222, 92.2948771345273, 95.2380952380952, 97.4137931034483, 
97.2222222222222, 93.8848920863309, 86.0730593607306, 92.0260782347041, 
98.0769230769231, 62.1794871794872, 93.2926829268293, 70, 5.58766859344894, 
95.1026856240126, 88.821752265861, 22.9357798165138, 68.4466019417476, 
91.2181303116147, 80, 95.7746478873239, 95.8333333333333), tipo = c("Departamental", 
"Departamental", "Municipal", "Departamental", "Municipal", "Departamental", 
"Municipal", "Distrital", "Municipal", "Distrital", "Departamental", 
"Departamental", "Municipal", "Municipal", "Municipal", "Departamental", 
"Municipal", "Departamental", "Distrital", "Municipal", "Departamental", 
"Departamental", "Departamental", "Municipal", "Departamental", 
"Municipal", "Departamental", "Municipal", "Departamental", "Municipal", 
"Municipal", "Municipal", "Municipal", "Municipal", "Municipal", 
"Municipal", "Municipal", "Municipal", "Departamental", "Departamental", 
"Departamental", "Municipal", "Municipal", "Municipal", "Municipal", 
"Departamental", "Municipal", "Municipal", "Departamental", "Municipal", 
"Municipal", "Municipal", "Municipal", "Departamental", "Municipal", 
"Municipal", "Departamental", "Municipal", "Departamental", "Municipal", 
"Municipal", "Municipal", "Municipal", "Municipal", "Municipal", 
"Departamental", "Municipal", "Departamental", "Municipal", "Municipal", 
"Departamental", "Municipal", "Municipal", "Departamental", "Distrital", 
"Departamental", "Municipal", "Municipal", "Municipal", "Municipal", 
"Departamental", "Departamental", "Municipal", "Municipal", "Municipal", 
"Municipal", "Municipal", "Departamental", "Municipal", "Departamental", 
"Departamental", "Municipal", "Municipal", "Municipal", "Municipal"
), rural = c(87.9432624113475, 87.1920135938828, 61.25, 81.8032786885246, 
19.6428571428571, 27.0096463022508, 30.3030303030303, 0.489396411092985, 
6.66666666666667, 2.24803297115024, 77.2442588726514, 84.0325342465753, 
6.66666666666667, 20.4907975460123, 31.0077519379845, 82.9002514668902, 
6.15128844555278, 94.7916666666667, 8.81801125703565, 14.6666666666667, 
86.5912762520194, 89.4032134659526, 79.1833466773419, 50, 92.1666666666667, 
55.7471264367816, 82.4182603331277, 15.8013544018059, 78.5690950669716, 
19.4630872483221, 19.047619047619, 15.7303370786517, 16.3265306122449, 
59.2105263157895, 12.568306010929, 36.7924528301887, 6.59340659340659, 
36.2745098039216, 93.4065934065934, 89.7435897435898, 86.8037135278515, 
26.5402843601896, 57.6642335766423, 6.59340659340659, 54.0983606557377, 
81.2091503267974, 80.3680981595092, 40, 69.5017182130584, 73.7556561085973, 
8.69565217391304, 28.5714285714286, 7.63723150357995, 86.4527629233512, 
55.2325581395349, 6.45161290322581, 90.2942468159859, 26.4900662251656, 
85.9764705882353, 25.7462686567164, 37.5478927203065, 39.4886363636364, 
60.3053435114504, 72.4867724867725, 24.609375, 90.1760889712697, 
50.3311258278146, 74.6575342465753, 67.9054054054054, 52.4590163934426, 
84.7039473684211, 35.4838709677419, 78.6324786324786, 47.2222222222222, 
22.0379146919431, 88.7592376507196, 20, 3.62903225806452, 34.8623853211009, 
0.33112582781457, 74.5689655172414, 80.1830663615561, 44.7674418604651, 
84.1954022988506, 7.01754385964912, 86.4864864864865, 98.1515711645102, 
73.8644304682041, 32.5333333333333, 92.4242424242424, 91.8103448275862, 
18.1102362204724, 53.0864197530864, 40.5405405405405, 21), Promedio = c(225, 
248.75, 245.75, 260.25, 271.25, 234.75, 271.25, 261.75, 266.25, 
277, 225.75, 258.75, 290, 229.5, 265.5, 249.5, 256.25, 240, 250.25, 
260.25, 256.25, 229.25, 239.5, 288.75, 204.5, 224.5, 236.5, 271.5, 
264.75, 272.25, 292.5, 289, 276.5, 263.75, 291.75, 269.25, 252, 
269.25, 241.5, 240.25, 256.75, 271, 276.25, 271.25, 256.25, 229.5, 
232.75, 247.25, 221.5, 238.25, 243, 274.5, 269.5, 252.75, 266.75, 
284.5, 252.75, 278.25, 259.75, 277, 281.5, 270.5, 280.5, 281.75, 
266.25, 251.5, 226.75, 255, 248.25, 281, 248.75, 286.25, 259, 
246, 246.5, 264.75, 265.5, 261.5, 285.25, 253, 236.25, 240.25, 
263, 217.75, 289.75, 219.25, 207.5, 248.5, 259.75, 221, 235.5, 
271.75, 274, 248.25, 280.75)), row.names = c(NA, -95L), class = "data.frame")
2 Answers

You can use ggrepel::geom_label_repel. Note that the label placements are semi-random, so you many need to draw the plot a few times, or mess with geom_label_repel parameters to get something you like.

enter image description here

Change your geom_label calls like below

  geom_label(data = tic[tic$etc=="ARMENIA",],
             aes(y = Promedio,
                 label = "Armenia"),
             size = 3,
             fontface = "bold")

to geom_label_repel calls

  geom_label_repel(data = tic[tic$etc=="ARMENIA",],
             aes(y = Promedio,
                 label = "Armenia"),
             size = 3,
             fontface = "bold")

If you are going to use ggrepel, it is better to have a single call to geom_label_repel. This means changing to a single geom_label_repel call like this:

geom_label_repel(data = tic[tic$etc %in% c("CALDAS","RISARALDA", "PEREIRA", 
                                           "ARMENIA", "QUINDÍO"),],
                 aes(y = Promedio, label = etc, fontface = "bold"),
                 size = 3)

This ensures that none of the groups are plotted on top of each other, and also makes your code shorter and more maintainable

enter image description here

Related