Search code examples
rggplot2vectordistancegeom-col

How to correct a different distance between bars in geom_col


I am making a geom_col in ggplot2. The x-axis is a numerical vector of timepoints (0, 6, 18, 24, 32, 44). There is a difference between each column corresponding to the numerical difference between each timepoint. But i want an equal distance between all the columns. I have searched for answers in here, but i didn't find a similar issue.

This is my code:

ggplot(data = ny_dataframe_scratch, aes(x=timepoint, y = relative_wound_healing, fill = Condition)) +
  geom_col(width = 5, position = position_dodge()) + 
  scale_x_continuous(breaks=c(0, 6, 18, 24, 32, 44), name = "Time point, hours") + 
  scale_y_continuous(name = "Relative scratch area") + 
  scale_fill_manual(values=c("palevioletred4", "slategray")) +
  geom_point(data = ny_dataframe_scratch, position = position_dodge(width = 5), aes(x=timepoint, y=relative_wound_healing, fill = Condition))

This is the output of dput():

structure(list(timepoint = c(0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 
6, 18, 18, 18, 18, 18, 18, 24, 24, 24, 24, 24, 24, 32, 32, 32, 
32, 32, 32, 44, 44, 44, 44, 44, 44), Condition = structure(c(2L, 
2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 
1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 
1L, 1L, 1L), .Label = c("Control", "Knockout"), class = "factor"), 
    relative_wound_healing = c(1, 1, 1, 1, 1, 1, 0.819981, 0.78227, 
    0.811902, 0.873852, 0.893572, 0.910596, 0.39819, 0.436948, 
    0.559486, 0.534719, 0.591295, 0.612154, 0.222731, 0.2592, 
    0.453575, 0.37238, 0.477891, 0.505393, 0.05243246, 0.0809449, 
    0.2108063, 0.261122, 0.3750218, 0.4129873, 0, 0.0240122, 
    0.0778219, 0.0806758, 0.2495444, 0.3203724)), class = "data.frame", row.names = c(NA, 
-36L))

Picture of how the graph looks:


Solution

  • The x-scale has proportional gaps because ‘ggplot2’ considers the values as continuous rather than categorical.

    To make it categorical, you can for instance use factors:

    aes(x = factor(timepoint, ordered = TRUE), …
    

    (Without ordered = TRUE, ‘ggplot2’ assumes alphabetical ordering, so it would put 11 before 5, which probably isn’t what you want.)

    To fix the bar heights, you need to compute and plot a summary statistic — ‘ggplot2’ allows you to do this using stat_summary (instead of geom_col):

    stat_summary(fun.y = mean, geom = "col", position = position_dodge())
    

    Taken together:

    ggplot(ny_dataframe_scratch) +
        aes(x = factor(timepoint, ordered = TRUE), y = relative_wound_healing, fill = Condition) +
        scale_fill_manual(values = c("palevioletred4", "slategray")) +
        stat_summary(fun.y = mean, geom = "col", position = position_dodge()) +
        geom_point(position = position_dodge(width = 1)) +
        labs(x = "Time point, hours", y = "Relative scratch area")