Home > database >  How to align labels with different length using geom_text in ggplot2?
How to align labels with different length using geom_text in ggplot2?

Time:03-29

I have added a caption to my plot using geom_text and I want to justify the labels to the left and right respectively (since I am using facet_grid and I have two different groups).

This is my example:

library(ggplot2)
library(dplyr)

# DATA
val1 <- c(2.1490626,2.2035281,1.5927854,3.1399245,2.3967338,3.7915825,4.6691277,3.0727319,2.9230937,2.6239759,3.7664386,4.0160378,1.2500835,4.7648343,0.0000000,5.6740227,2.7510256,3.0709322,2.7998003,4.0809085,2.5178086,5.9713330,2.7779843,3.6724801,4.2648527,3.6841084,2.5597235,3.8477471,2.6587736,2.2742209,4.5862788,6.1989269,4.1167091,3.1769325,4.2404515,5.3627032,4.1576810,4.3387921,1.4024381,0.0000000,4.3999099,3.4381837,4.8269218,2.6308474,5.3481382,4.9549753,4.5389650,1.3002293,2.8648220,2.4015338,2.0962332,2.6774765,3.0581759,2.5786137,5.0539080,3.8545796,4.3429043,4.2233248,2.0434363,4.5980727)
val2 <- c(3.7691229,3.6478055,0.5435826,1.9665861,3.0802654,1.2248374,1.7311236,2.2492826,2.2365337,1.5726119,2.0147144,2.3550348,1.9527204,3.3689502,1.7847986,3.5901329,1.6833872,3.4240479,1.8372175,0.0000000,2.5701453,3.6551315,4.0327091,3.8781182)
val3 <- c(2.1490626,2.2035281,1.5927854,3.1399245,2.3967338,3.7915825,4.6691277,3.0727319,2.9230937,2.6239759,3.7664386,4.0160378,1.2500835,4.7648343,0.0000000,5.6740227,2.7510256,3.0709322,2.7998003,4.0809085,2.5178086,5.9713330,2.7779843,3.6724801,4.2648527,3.6841084,2.5597235,3.8477471,2.6587736,2.2742209,4.5862788,6.1989269,4.1167091,3.1769325,4.2404515,5.3627032,4.1576810,4.3387921,1.4024381,0.0000000,4.3999099,3.4381837,4.8269218,2.6308474,5.3481382,4.9549753,4.5389650,1.3002293,2.8648220,2.4015338,2.0962332,2.6774765,3.0581759,2.5786137,5.0539080,3.8545796,4.3429043,4.2233248,2.0434363,4.5980727)

df1 <- data.frame(value = val1)   
df2 <- data.frame(value = val2)   
df3 <- data.frame(value = val3)   

data <- bind_rows(lst(df1, df2, df3), .id = 'id')
data$Sex <- rep(c("Male", "Female"), times=72)
data$d <- "ff"
data <- as.data.frame(unclass(data), stringsAsFactors = TRUE)

# PLOT

p <- data %>% 
  ggplot(aes(value))  
  geom_density(lwd = 1.2, colour="red", show.legend = FALSE)  
  geom_histogram(aes(y=..density.., fill = id), bins=10, col="black", alpha=0.2)  
  facet_grid(id ~ Sex )  
  xlab("type_data")   
  ylab("Density")  
  ggtitle("title")  
  guides(fill=guide_legend(title="legend_title"))  
  theme(strip.text.y = element_blank())

p

# ADD CAPTION

caption_df = data.frame(value = c(min(data$value), max(data$value)), id = c(rep(tail(levels(data$id), n=1), times=length(levels(data$Sex)))),
                        Sex = c(levels(data$Sex)))
caption_df$txt = c("This is the first caption \nThis is the second caption", "This is the first caption \nThis is the second caption")


yrange <- layer_scales(p)$y$range$range
ypos <- min(yrange) - 0.4 * diff(yrange)


p   coord_cartesian(clip = "off", 
                    ylim = layer_scales(p)$y$range$range, 
                    xlim = layer_scales(p)$x$range$range)  
  geom_text(data = caption_df,
            aes(y = ypos, label = txt))  
  theme(plot.margin = unit(c(1,1,2,1), "cm"))

This is how it looks: enter image description here

This is what I want:

enter image description here

I have tried using hjust=0 but it doesn't look nice (they are both displaced)

enter image description here

I tried with hjust=1 but I have the same problem (displaced): enter image description here

vjust doesn't give me what I need either.

Does anyone have an idea about how to solve it?

Thanks in advance

CodePudding user response:

You can use hjust and nudge_x together in geom_text.

hjust = 0 will left-align the text, but also shifting the location of the text. nudge_x helps to counteract the effect of hjust by adding some "padding" around the text.

Try out different values of nudge_x to see which one best fit your goal.

library(ggplot2)

data %>% 
  ggplot(aes(value))  
  geom_density(lwd = 1.2, colour="red", show.legend = FALSE)  
  geom_histogram(aes(y=..density.., fill = id), bins=10, col="black", alpha=0.2)  
  facet_grid(id ~ Sex )  
  xlab("type_data")   
  ylab("Density")  
  ggtitle("title")  
  guides(fill=guide_legend(title="legend_title"))  
  theme(strip.text.y = element_blank())   
  coord_cartesian(clip = "off", 
                  ylim = layer_scales(p)$y$range$range, 
                  xlim = layer_scales(p)$x$range$range)  
  geom_text(data = caption_df,
            aes(y = ypos, label = txt), hjust = 0, nudge_x =  -1)  
  theme(plot.margin = unit(c(1,1,2,1), "cm"))

nudge_x

  • Related