R como colocar texto no ggplot em relação ao eixo

Sep 24 2020

Estou tentando usar geom_text () no ggplot para colocar tamanhos de amostra em um gráfico de barras com limites definidos determinados pelo ggplot. Para a maioria dos meus gráficos, consegui especificar o valor y para o posicionamento do texto como 0. No entanto, para alguns gráficos, as barras CI se estendem abaixo de 0.

Para evitar a impressão dos tamanhos de amostra nas barras CI, desejo gerar um código que especifique o valor y para geom_text () em relação à margem do gráfico que define o eixo x. A ideia seria gerar um código geral relativo ao eixo x para que esse código pudesse ser aplicado a todos os meus gráficos, independentemente de onde o valor mínimo de y esteja no gráfico. Idealmente, eu gostaria de ajustar meu código de plotagem para conseguir isso, se possível. Agradecemos antecipadamente por sua contribuição!

Banco de dados de plotagem

data <- structure(list(Site_long = structure(c(2L, 2L, 1L, 1L), .Label = c("Hanauma Bay", 
"Waikiki"), class = "factor"), Shelter = structure(c(1L, 2L, 
1L, 2L), .Label = c("Low", "High"), class = c("ordered", "factor"
)), mean = c(0.096818329015544, 0.140368187765273, 0.364490168863912, 
0.452663275851282), sd = c(0.358269615215823, 0.442381836749624, 
0.431417057945072, 0.461599742148954), lower = c(-0.13725115292546, 
-0.148654612244481, 0.198658790631641, 0.337761753133984), upper = c(0.330887810956549, 
0.429390987775027, 0.530321547096184, 0.56756479856858), sample_size = c(9L, 
9L, 26L, 62L)), row.names = c(NA, -4L), groups = structure(list(
    Site_long = structure(1:2, .Label = c("Hanauma Bay", "Waikiki"
    ), class = "factor"), .rows = structure(list(3:4, 1:2), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = 1:2, class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

Código de lote

mult_compare_growth_all <- c("AB", "B", "A", "AB")

growth_plot <- ggplot(data = data, aes(fill=Shelter, y=mean, x=Site_long)) + 
  geom_bar(position = "dodge", stat="identity", width = .8) +
  scale_x_discrete(limits = position) +
  geom_errorbar(aes(ymin = lower, ymax = upper), position = position_dodge(.8), width = .1) +
  geom_text(aes(label = mult_compare_growth_all, y = data$upper), vjust = -.5, position = position_dodge(width = 0.8), size = 4) +
  scale_fill_grey(name = "Shelter", start = .8, end = .2) +
  labs(x = "Site", y = expression(paste("Coral growth (cm"^"2","/quarter)"))) +
  theme_classic(base_size = 14.5) +
  theme(text = element_text(size = 18), legend.position = "none", 
        axis.title.x = element_blank(),
        axis.text.y = element_text(angle = 90),
        axis.text.x = element_blank())

Respostas

1 rodolfoksveiga Sep 24 2020 at 05:14

Você pode usar y = -Infpara orientar a posição do texto. Para manter o texto dentro do gráfico, você deve acoplar um vjustfator Inf, caso contrário, o texto sairá do gráfico.

Aqui está o código:

ggplot(data = data, aes(fill=Shelter, y=mean, x=Site_long)) + 
  geom_bar(position = "dodge", stat = "identity", width = .8) +
  geom_errorbar(aes(ymin = lower, ymax = upper), position = position_dodge(.8), width = .1) +
  geom_text(aes(label = mult_compare_growth_all, y = data$upper), vjust = -.5,
            position = position_dodge(width = .8), size = 4) +
  geom_text(aes(label = sample_size, y = -Inf), vjust = -.3,
            position = position_dodge(width = .8)) +
  scale_fill_grey(name = "Shelter", start = .8, end = .2) +
  labs(x = "Site", y = expression(paste("Coral growth (cm"^"2","/quarter)"))) +
  theme_classic(base_size = 14.5) +
  theme(text = element_text(size = 18), legend.position = "none", 
        axis.title.x = element_blank(),
        axis.text.y = element_text(angle = 90),
        axis.text.x = element_blank())

E a saída:

Deixe-me saber se é isso que você está procurando.

1 Duck Sep 24 2020 at 05:14

Talvez, como sugestão, você possa calcular um fator de posicionamento com pfbase no valor mínimo de sua lowervariável e adicionar alguma quantidade de ajuste como este:

library(ggplot2)
#Plot
mult_compare_growth_all <- c("AB", "B", "A", "AB")
#Factor for placement
pf <- min(data$lower)-0.02
#Code
ggplot(data = data, aes(fill=Shelter, y=mean, x=Site_long)) + 
  geom_bar(position = "dodge", stat="identity", width = .8) +
  geom_text(aes(y=pf,label=sample_size),position = position_dodge(0.8))+
  geom_errorbar(aes(ymin = lower, ymax = upper), position = position_dodge(.8), width = .1) +
  geom_text(aes(label = mult_compare_growth_all, y = upper),
            vjust = -.5, position = position_dodge(width = 0.8), size = 4)+
  scale_fill_grey(name = "Shelter", start = .8, end = .2) +
  labs(x = "Site", y = expression(paste("Coral growth (cm"^"2","/quarter)"))) +
  theme_classic(base_size = 14.5) +
  theme(text = element_text(size = 18), legend.position = "none",
        axis.title.x = element_blank(),
        axis.text.y = element_text(angle = 90),
        axis.text.x = element_blank())

Resultado:

brianavery Sep 24 2020 at 05:57

por algum motivo, quando ploto isso, o meu é invertido (provavelmente ordem dos fatores), mas acho que é isso que você quer?

ggplot(data = data, aes(fill=Shelter, y=mean, x=Site_long)) + 
  geom_col(aes(fill=Shelter), position = "dodge", width = 0.8) + 
  geom_text(aes(y=lower, group=Shelter, label = sample_size), 
            position = position_dodge(width = 0.8), vjust=1.5) +
  geom_errorbar(aes(ymin = lower, ymax = upper), 
                position = position_dodge(.8), width = .1) +
  geom_text(aes(label = mult_compare_growth_all, y = data$upper), vjust = -.5, 
            position = position_dodge(width = 0.8), size = 4) +
  scale_fill_grey(name = "Shelter", start = .8, end = .2) +
  labs(x = "Site", y = expression(paste("Coral growth (cm"^"2","/quarter)"))) +
  theme_classic(base_size = 14.5) +
  theme(text = element_text(size = 18), legend.position = "none", 
        axis.title.x = element_blank(),
        axis.text.y = element_text(angle = 90),
        axis.text.x = element_blank())

resultados:

Deixe-me decifrar um pouco:

Usei geom_col()uma vez que foi construído para este tipo de gráfico de barra com a altura especificada por um único valor. Também pode ser feito geom_bar()da maneira que você fez.

Então geom_text()você precisa da groupestética para colocar rótulos nas barras corretas, e você tem que especificar o y=lowerque coloca o rótulo exatamente (irritantemente) na parte inferior da barra de erro, mas o vjustmove para baixo. O valor ( 1.5) provavelmente tem algum significado, mas não sei o que é e tive que mexer nele para que essa parte não seja automática.