Search code examples
rggplot2labelaxis-labelsgeom-bar

How to change the tick labels on an axis


I have tried to put as much information here as possible. I hope my question makes sense. This is my first time using stack overflow. I am making plots of behavioural data. I have measures the activity of animals over time whilst being exposed to varying stimuli. The stimuli range between no stimuli (REST in this example), a vibration (VIBRATION in this example) and a light flash (PULSE in this example). I am trying to replicate some figures that I have made in excel. The excel figure looks like this:

Figure from excel

I am using a MacOS version 11.2.1

packages I am using include:

library(tidyverse)
library(tidyr)
library(tibble)
library(ggplot2)
library(ggpubr) 
library(dplyr) 
library(plyr)

I have summarised my raw data using this code:

  mydata <- ddply(df, c("BLOCK", "SEQ_BIN", "CONDITION"), summarise,
                   N    = length(distance),
                   mean = mean(distance),
                   sd   = sd(distance),
                   se   = sd / sqrt(N))

This gives me the correct data set which looks like this:

  BLOCK SEQ_BIN CONDITION  N      mean       sd        se
1     1       1     PULSE 48 3.3416667 2.364258 0.3412513
2     1       2      REST 48 0.7354167 1.408257 0.2032644
3     1       3      REST 48 1.0250000 1.483885 0.2141804
4     1       4      REST 48 0.8708333 1.377935 0.1988878
5     1       5      REST 48 0.7604167 1.379136 0.1990612
6     1       6      REST 48 1.1270833 1.271578 0.1835365

I have also included the full dataset here:

structure(list(BLOCK = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L), SEQ_BIN = c(1, 2, 3, 4, 5, 6, 7, 8, 
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 1, 2, 3, 
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 
37, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 
34, 35, 36, 37), CONDITION = c("PULSE", "REST", "REST", "REST", 
"REST", "REST", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "PULSE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "REST", "REST", "REST", "REST", 
"REST", "PULSE", "REST", "REST", "REST", "REST", "REST", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "PULSE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "REST", "REST", "REST", "REST", "REST", "PULSE", "REST", 
"REST", "REST", "REST", "REST", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "PULSE", 
"VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "VIBRATE", "REST", 
"REST", "REST", "REST", "REST"), N = c(48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 48L, 
48L, 48L), mean = c(3.34166666666667, 0.735416666666667, 1.025, 
0.870833333333333, 0.760416666666667, 1.12708333333333, 2.32291666666667, 
1.16875, 0.758333333333333, 0.625, 0.633333333333333, 0.35, 0.36875, 
0.35, 0.277083333333333, 0.227083333333333, 0.21875, 0.56875, 
0.495833333333333, 0.533333333333333, 0.335416666666667, 0.445833333333333, 
0.34375, 0.0291666666666667, 0.129166666666667, 0.0354166666666667, 
1.00625, 0.0291666666666667, 0.2125, 0.225, 0.139583333333333, 
0.283333333333333, 0.139583333333333, 0.235416666666667, 0.35, 
0.2375, 0.225, 3.32083333333333, 0.554166666666667, 0.75625, 
0.69375, 0.395833333333333, 0.404166666666667, 3.46041666666667, 
1.325, 0.53125, 0.441666666666667, 0.270833333333333, 0.204166666666667, 
0.210416666666667, 0.164583333333333, 0.158333333333333, 0.0708333333333333, 
0.139583333333333, 0.0708333333333333, 0.252083333333333, 0.122916666666667, 
0.225, 0.341666666666667, 0.108333333333333, 0.258333333333333, 
0.35625, 0.25625, 0.98125, 0.108333333333333, 0.09375, 0.0645833333333333, 
0.0395833333333333, 0.1, 0.0354166666666667, 0.11875, 0.2125, 
0.139583333333333, 0, 2.24375, 0.54375, 0.654166666666667, 0.45, 
0.725, 0.435416666666667, 2.23333333333333, 0.764583333333333, 
0.49375, 0.345833333333333, 0.139583333333333, 0.329166666666667, 
0.16875, 0.122916666666667, 0.104166666666667, 0.164583333333333, 
0.0291666666666667, 0.0354166666666667, 0.40625, 0.145833333333333, 
0.15, 0.075, 0.075, 0.0979166666666667, 0, 0.135416666666667, 
0.66875, 0.0291666666666667, 0.0291666666666667, 0.0645833333333333, 
0.0583333333333333, 0, 0.0291666666666667, 0, 0.0875, 0.0645833333333333, 
0.164583333333333), sd = c(2.36425808913848, 1.4082567438992, 
1.48388506752276, 1.3779352937489, 1.37913626736869, 1.27157794137556, 
2.55769507135119, 2.2472826380585, 1.28341852899488, 1.37724671378744, 
1.31283894644042, 1.10299399122609, 0.829035905081857, 1.07624247841294, 
1.34484667849256, 0.64436661407411, 0.928429525046852, 2.49494435617822, 
2.02809609211823, 2.23895238927013, 1.8469629566184, 3.0888239401645, 
2.18455957389925, 0.202072594216369, 0.529535458131408, 0.245373864405591, 
1.26531574564225, 0.202072594216369, 0.668636274879778, 1.00095698889464, 
0.587000881993369, 0.991095103179357, 0.599197897666018, 0.747332727554306, 
1.30171735991589, 0.69851666545251, 0.616613952126812, 2.5305754398432, 
1.41029019698653, 1.47704510223708, 1.47394480828569, 0.902704761549878, 
1.03922195391723, 2.7874139302299, 2.05193214603088, 1.04640341474165, 
1.0162160377897, 0.691885592969579, 0.555421378595944, 0.669785479577217, 
0.584367118409322, 0.568998124116615, 0.34329959208988, 0.787060132697794, 
0.34329959208988, 0.930565964445507, 0.413721863263043, 0.723319769784915, 
1.43064236923575, 0.580474249738892, 0.73276896400566, 2.23110565568028, 
1.08704288509817, 1.4658751289305, 0.580474249738892, 0.368669978695702, 
0.314534159653053, 0.274241377865072, 0.526732198095615, 0.245373864405591, 
0.648617597073994, 0.831718293143139, 0.739677785897586, 0, 2.25160994411233, 
1.15591103427078, 1.4281305043968, 0.999148573706846, 1.60352006402935, 
1.07079004107095, 2.91279885387243, 1.62970948766472, 1.28798147370051, 
1.21549540435749, 0.599197897666018, 0.917433592781036, 0.504092295669346, 
0.521960128636781, 0.41869012221417, 0.581081011429535, 0.202072594216369, 
0.245373864405591, 1.41397376514228, 0.589250636025739, 0.661719230811325, 
0.364078551262446, 0.519615242270663, 0.387841590460307, 0, 0.938194187433142, 
0.86814947482464, 0.202072594216369, 0.202072594216369, 0.314534159653053, 
0.282717311132842, 0, 0.202072594216369, 0, 0.342472238353057, 
0.314534159653053, 0.602650028405864), se = c(0.341251261049463, 
0.203264352544578, 0.214180360795183, 0.198887828192953, 0.199061173803622, 
0.183536466687192, 0.369171484487398, 0.324367309007061, 0.185245508299537, 
0.198788440236426, 0.1894919797825, 0.15920346943723, 0.119661025741719, 
0.155342221156255, 0.194111897961614, 0.0930063095231238, 0.134007259052349, 
0.360114198913158, 0.292730456181722, 0.323164941161967, 0.266586140046725, 
0.445833333333333, 0.315314014512877, 0.0291666666666667, 0.076431859824405, 
0.0354166666666667, 0.182632596589107, 0.0291666666666667, 0.0965093333229472, 
0.144475696746389, 0.0847262793083548, 0.14305225615328, 0.0864867668788333, 
0.107868187856924, 0.187886717039061, 0.100822196208112, 0.0890005578116235, 
0.365257102849531, 0.203557856216416, 0.213193096845449, 0.212745607958599, 
0.130294209269895, 0.14999876871047, 0.402328545740287, 0.296170894217444, 
0.151035323295508, 0.146678150743174, 0.0998650833373525, 0.0801681706115103, 
0.0966752067333022, 0.0843461282797969, 0.08212780503178, 0.0495510279764452, 
0.113602344870374, 0.0495510279764452, 0.134315627517829, 0.0597156072811378, 
0.104402215948875, 0.206495439248086, 0.0837842410860988, 0.105766089655618, 
0.322032362724376, 0.156901125583024, 0.211580850071601, 0.0837842410860988, 
0.0532129278605243, 0.0453990954362558, 0.0395833333333333, 0.0760272440903367, 
0.0354166666666667, 0.0936198860679497, 0.120048195109032, 0.106763292200389, 
0, 0.324991901835823, 0.166841386698873, 0.206132882787852, 0.14421467449752, 
0.231448185154577, 0.154555229614472, 0.420426300594621, 0.235228302851028, 
0.18590411263806, 0.175441649726138, 0.0864867668788333, 0.132420132938934, 
0.0727594556502784, 0.0753384551936743, 0.060432713691847, 0.0838718195924555, 
0.0291666666666667, 0.0354166666666667, 0.204089533482991, 0.0850510033324046, 
0.0955109440092177, 0.0525502123943856, 0.075, 0.0559801116637976, 
0, 0.135416666666667, 0.12530658324671, 0.0291666666666667, 0.0291666666666667, 
0.0453990954362558, 0.0408067289217784, 0, 0.0291666666666667, 
0, 0.0494316097507778, 0.0453990954362558, 0.0869850390318153
)), class = "data.frame", row.names = c(NA, -111L))

I then try to make my figure. I like that R easily lets me break up the large figure from excel into blocks using facet_wrap. However, if I use "CONDITION" for the x axis I get the correct labels but it is summarised and I do not want this. See code and figure below:

ggplot(mydata, aes(x = CONDITION, y = mean)) +
  geom_bar(stat="identity") +
  facet_wrap(~BLOCK, ncol = 1) +
  ggtitle("habituation (vibration)") +
  theme(legend.position = "none", plot.title = element_text(hjust = 0.5)) +
  labs(x = "condition", y = "distance")

right labels wrong data right labels wrong data

If I instead use the time bin data (SEQ_BIN in this example). I get the correct data the same as the figure in excel but it is numbered rather than having the labels of what stimuli the animals are receiving at the time. See code and figure below:

ggplot(mydata, aes(x = SEQ_BIN, y = mean)) +
  geom_bar(stat="identity") +
  facet_wrap(~BLOCK, ncol = 1) +
  ggtitle("habituation (vibration)") +
  theme(legend.position = "none", plot.title = element_text(hjust = 0.5)) +
  labs(x = "condition", y = "distance")

enter image description here

Is there an easy way that I can change the tick labels in that last figure in ggplot to use the labels from "CONDITION" but over time?


Solution

  • One way to do it would be to use geom_text to label along the x axis for each bar's condition. You might have to play around with the spacing between plots (and between axis labels and plots) to get it to fit well and show all text clearly:

    library(tidyverse)
    
    df <- tibble(
      BLOCK = rep(1:3, each = 20),
      SEQ_BIN = rep(1:20, times = 3),
      CONDITION = case_when(
        SEQ_BIN == 1 ~ "PULSE",
        SEQ_BIN == 17 ~ "VIBRATE",
        TRUE ~ "REST"
      ),
      mean = rnorm(60, 5, 2)
    )
    
    df %>% 
      ggplot(aes(SEQ_BIN, mean)) +
      geom_bar(stat = "identity") +
      facet_wrap(~ BLOCK, ncol = 1) +
      ggtitle("habituation (vibration)") +
      theme(legend.position = "none", plot.title = element_text(hjust = 0.5),
            # These lines replace x axis ticks with labels and space things out
            axis.text.x = element_blank(),
            axis.ticks.x = element_blank(),
            panel.spacing = unit(2, "cm"),
            axis.title.x = element_text(margin = margin(2, unit = "cm"))) +
      labs(x = "condition", y = "distance") +
      geom_text(aes(y = -1, label = CONDITION), angle = 90, hjust = 1) +
      # This ensures it doesn't cut the text off or expand the lower axis to include text
      coord_cartesian(clip = "off", ylim = c(0, NA))
    

    (All done on synthetic data in an attempt to mirror your own)

    Created on 2021-03-15 by the reprex package (v1.0.0)