Ggplot2: Есть ли исправление для зубчатого, некачественного текста, созданного geom_text()?

При добавлении текста аннотации к сюжету я заметил, что geom_text() создал неприглядный, неровный текст, а annotate() - гладкий, красивый текст. Кто-нибудь знает, почему это происходит, и есть ли способ исправить это? Я знаю, что могу просто использовать annotate() здесь, но, вероятно, есть случаи, когда geom_text() предпочтительнее, и я хотел бы найти исправление. Кроме того, geom_text() не может быть предназначен для создания плохого текста, так что либо я делаю что-то неправильно, либо я сталкивался с каким-то тонким побочным эффектом.

Вот некоторые поддельные данные и код для создания графика, а также изображение, показывающее результаты.

library(ggplot2)
age = structure(list(age = c(41L, 40L, 43L, 44L, 40L, 42L, 44L, 45L, 
        44L, 41L, 43L, 40L, 43L, 43L, 40L, 42L, 43L, 44L, 43L, 41L)), 
        .Names = "age", row.names = c(NA, -20L), class = "data.frame")
ggplot(age, aes(age)) + 
  geom_histogram() +
  scale_x_continuous(breaks=seq(40,45,1)) +
  stat_bin(binwidth=1, color="black", fill="blue") +
  geom_text(aes(41, 5.2, 
            label=paste("Average = ", round(mean(age),1))), size=12) +
  annotate("text", x=41, y=4.5, 
           label=paste("Average = ", round(mean(age$age),1)), size=12)

enter image description here

Ответ 1

geom_text, несмотря на то, что он ничего не использует непосредственно из файла age data.frame, все еще использует его для своего источника данных. Поэтому он помещает 20 копий "Среднее = 42,3" на сюжет, по одному для каждой строки. Это то, что многократная перезапись делает ее такой плохой. geom_text предназначен для размещения текста на графике, где информация поступает из файла data.frame(который он предоставляется прямо или косвенно в исходном вызове ggplot). annotate предназначен для простых одноразовых дополнений, как у вас (он создает geom_text, заботясь о источнике данных).

Если вы действительно хотите использовать geom_text(), просто reset источник данных:

ggplot(age, aes(age)) + 
  scale_x_continuous(breaks=seq(40,45,1)) +
  stat_bin(binwidth=1, color="black", fill="blue") +
  geom_text(aes(41, 5.2, 
            label=paste("Average = ", round(mean(age$age),1))), size=12,
            data = data.frame()) +
  annotate("text", x=41, y=4.5, 
           label=paste("Average = ", round(mean(age$age),1)), size=12)

enter image description here

Ответ 2

Попробуйте geom_text(..., check_overlap = TRUE) *

Из документации ?geom_text, check_overlap говорит:

Если TRUE, текст, который перекрывает предыдущий текст в том же слое, не будет нанесен.

library(ggplot2)
age = structure(list(age = c(41L, 40L, 43L, 44L, 40L, 42L, 44L, 45L, 
                             44L, 41L, 43L, 40L, 43L, 43L, 40L, 42L, 43L, 44L, 43L, 41L)), 
                .Names = "age", row.names = c(NA, -20L), class = "data.frame")

ggplot(age, aes(age)) + 
  geom_histogram() +
  stat_bin(binwidth=1) +
  geom_text(aes(41, 5.2, label=paste("Average = ", round(mean(age),1))), 
            size=12, 
            check_overlap = TRUE) 

* Это, по сути, ответ, который Дейв Грюневальд разместил в комментарии к Брайану.Я просто пытаюсь сделать этот ответ более заметным!