Simon Turner
Simon Turner

Reputation: 1

Is there a way in ggplot2 to fit several columns of text, minimising the space between them?

I'm trying to use RStudio and ggplot2. I have a list of studies, some information about their data and another couple of columns of numbers. What I would like is a plot where I could fix the size of the font (in points or mm or whatever) and have the plot height and width calculated and set to display the data with minimal gaps.

I know that the plot windows are re-sizable and that many of the things then automatically re-scale, but I don't really want that to be an option?

columns of text

So in this image I'd like the numbers columns to be a bit closer to the others.

I'm trying to do this programatically as I'll have lots of similar things with different length strings/different numbers of items, so the image size will sometimes be taller, sometimes wider etc.

I don't really know what I'm doing, I have tried using strwidth to estimate the width of the longest string, then used that to create a graph that was as high as the number of items and as wide as the width of the longest string.

Then I plotted the text based on newly calculated strwidths.

Of course, when I resize the window everything changes, but I don't really want to be able to resize.

I'm not super familiar with R (obviously that shows!)

Any help warmly received (or just letting me know that it's not possible/my idea doesn't make sense)!

structure(list(display_order = 1:12, study_ID = c("Pillay 2019", 
"Carr 2016", "Parry 2015", "Mansi 2018", "Maruyama 2017", "Turner 2024", 
"Talbot 2020", "Morgan 2021", "Viester 2021", "Aittasalo 2019", 
"Forbes 2018", "Linde 2022"), summary_data = c("Direction only", 
"MD (95% CI)", "MD (95% CI)", "MD (95% CI)", "Dichotomous data", 
"N", "MD (95% CI)", "Direction (p>0.05)", "Direction (specific p-value)", 
"MD (SE)", "Direction (specific p-value)", "No direction (specific p-value)"
), ft_n = c(11L, 20L, 23L, 27L, 30L, 40L, 50L, 55L, 78L, 89L, 
150L, 215L), fc_n = c(8L, 20L, 27L, 31L, 32L, 40L, 44L, 55L, 
78L, 92L, 150L, 215L), name_length = c(1.01267026665898, 0.933760895231004, 
1.01267026665898, 1.07842807618229, 1.48612649522681, 1.10473119999161, 
1.09157963808695, 1.22309525713357, 1.18364057141958, 1.32830775237087, 
1.18364057141958, 1.0389733904683), summary_data_length = c(1.23624681903823, 
1.18364057141958, 1.18364057141958, 1.18364057141958, 1.67024836189208, 
0.144667180951282, 1.18364057141958, 1.65709679998742, 2.43303895236248, 
0.802245276184384, 2.43303895236248, 2.70922175236038), ft_n_length = c(0.236728114283917, 
0.236728114283917, 0.236728114283917, 0.236728114283917, 0.236728114283917, 
0.236728114283917, 0.236728114283917, 0.236728114283917, 0.236728114283917, 
0.236728114283917, 0.355092171425875, 0.355092171425875), fc_n_length = c(0.118364057141958, 
0.236728114283917, 0.236728114283917, 0.236728114283917, 0.236728114283917, 
0.236728114283917, 0.236728114283917, 0.236728114283917, 0.236728114283917, 
0.236728114283917, 0.355092171425875, 0.355092171425875), x = c(3.88541666666667, 
3.88541666666667, 3.88541666666667, 3.88541666666667, 3.88541666666667, 
3.88541666666667, 3.88541666666667, 3.88541666666667, 3.88541666666667, 
3.88541666666667, 3.88541666666667, 3.88541666666667)), row.names = c(NA, 
12L), class = "data.frame")
library(ggplot2)

# keep the things we want to plot
MA_data_text <- subset(MA_data, select=c("display_order","study_ID","summary_data","ft_n","fc_n" ))

################################################################################
# find the width of the strings
MA_data_text$name_length <- strwidth(MA_data_text$study_ID, units="inches")
# find the maximum width
study_ID.max_value <- max(MA_data_text$name_length,na.rm=TRUE)
# summary data value to plot at is...
summary_data_x_coord <- study_ID.max_value

# n1
# find the width of the strings
MA_data_text$summary_data_length <- strwidth(MA_data_text$summary_data, units="inches")
# find the maximum width
summary_data.max_value <- max(MA_data_text$summary_data_length,na.rm=TRUE)
# n1 data value to plot at is...
n1_x_coord <- study_ID.max_value + summary_data.max_value

# n2
# find the width of the strings
MA_data_text$ft_n_length <- strwidth(MA_data_text$ft_n, units="inches")
# find the maximum width
ft_n.max_value <- max(MA_data_text$ft_n_length,na.rm=TRUE)
# n2 data value to plot at is...
n2_x_coord <- study_ID.max_value + summary_data.max_value + ft_n.max_value

# find the width of n2 to find the maximum needed
MA_data_text$fc_n_length <- strwidth(MA_data_text$fc_n, units="inches")
# find the maximum width
fc_n.max_value <- max(MA_data_text$fc_n_length,na.rm=TRUE)
# end data value to plot at is...
end_x_coord <- study_ID.max_value + summary_data.max_value + ft_n.max_value + fc_n.max_value

################################################################################

# make a box to put the text in
MA_data_text$x <- end_x_coord

MA_text_plot <- ggplot(MA_data_text)
# set the figure
MA_text_plot <- MA_text_plot + geom_point(aes(x=x,y=display_order), color="white", alpha=0)

################################################################################
# find the width of the strings
MA_data_text$name_length <- strwidth(MA_data_text$study_ID)
# find the maximum width
study_ID.max_value <- max(MA_data_text$name_length,na.rm=TRUE)
# summary data value to plot at is...
summary_data_x_coord <- study_ID.max_value

# n1
# find the width of the strings
MA_data_text$summary_data_length <- strwidth(MA_data_text$summary_data)
# find the maximum width
summary_data.max_value <- max(MA_data_text$summary_data_length,na.rm=TRUE)
# n1 data value to plot at is...
n1_x_coord <- study_ID.max_value + summary_data.max_value

# n2
# find the width of the strings
MA_data_text$ft_n_length <- strwidth(MA_data_text$ft_n)
# find the maximum width
ft_n.max_value <- max(MA_data_text$ft_n_length,na.rm=TRUE)
# n2 data value to plot at is...
n2_x_coord <- study_ID.max_value + summary_data.max_value + ft_n.max_value

# find the width of n2 to find the maximum needed
MA_data_text$fc_n_length <- strwidth(MA_data_text$fc_n)
# find the maximum width
fc_n.max_value <- max(MA_data_text$fc_n_length,na.rm=TRUE)
# end data value to plot at is...
end_x_coord <- study_ID.max_value + summary_data.max_value + ft_n.max_value + fc_n.max_value

################################################################################

# add some text
MA_text_plot <- MA_text_plot + geom_text(aes(x=0,y=display_order,label=study_ID),hjust="left",vjust="center")

MA_text_plot <- MA_text_plot + geom_text(aes(x=summary_data_x_coord,y=display_order,label=summary_data),hjust="left",vjust="center")

MA_text_plot <- MA_text_plot + geom_text(aes(x=n1_x_coord,y=display_order,label=ft_n),hjust="left",vjust="center")

MA_text_plot <- MA_text_plot + geom_text(aes(x=n2_x_coord,y=display_order,label=fc_n),hjust="left",vjust="center")

MA_text_plot```

Upvotes: 0

Views: 60

Answers (1)

Michiel Duvekot
Michiel Duvekot

Reputation: 1881

To reduce the vertical spacing of text in a chart, set the aspect ratio as a single value or (height/width) of the plot with theme(). For example:

MA_text_plot+
  theme(aspect.ratio=1/4)

Upvotes: 0

Related Questions