Anne Elise
Anne Elise

Reputation: 163

Grouped boxplot with two Y axis

I want to make two boxplots with different information for the same category, with two Y axes, using GGPLOT2. Looks like this chart below:

enter image description here

I have two category information (speed and angle of rotation) for the areas (AM and AR) and I want to combine these two movement patterns in a graphic grouped according to the areas.

so far my code looks like this:

areaveleang <- ggplot(dados2, aes(x = area)) +
        geom_boxplot(aes(y = speed, color="Bruto" ), fill = "darkblue", alpha=0.7) +
  geom_boxplot(aes(y = angulo_modulo), color="#a50026", position = "dodge") +
        scale_y_continuous(name = "speed (km/h)", sec.axis = sec_axis(~ . *6,name=expression("turn angle (graus)"))) +
                           #breaks = seq(0, 175, 25),
                           #limits=c(0, 175)) +
        scale_x_discrete(name = "Area") +
        #ggtitle("Boxplot of mean ozone by month") +
        theme_bw() +
        theme(plot.title = element_text(size = 14, family = "Tahoma", face = "bold"),
              text = element_text(size = 12, family = "Tahoma"),
              axis.title = element_text(face="bold"),
              axis.text.x=element_text(size = 11),
              legend.position = "bottom") +
        scale_fill_brewer(palette = "Accent")

Part of my data:

structure(list(lon = c(-38.8745, -38.8676, -38.9445, -38.9811, 
-38.9322, -38.9386), lat = c(-14.09437, -14.25664, -14.34518, 
-14.51857, -14.95994, -15.41684), bmode = c(1.396, 1.375, 1.346, 
1.248, 1.074, 1.289), bmode.5 = c(1, 1, 1, 1, 1, 1), ID = structure(c(53L, 
53L, 53L, 53L, 53L, 53L), .Label = c("10946.05", "20162.03", 
"21792.03", "21800.03", "21810.03", "24640.03", "24641.05", "24642.03", 
"27258.05", "27259.03", "27261.03", "27261.05", "27261.07", "33000.05", 
"37231.07", "37234.05", "37288.07", "42521.07", "50682.07", "50687.07", 
"60004.07", "81122.09", "81123.09", "81124.09", "81125.09", "81126.09", 
"84497.1", "87632.12", "87759.08", "87761.08", "87762.08", "87763.08", 
"87764.08", "87765.08", "87766.08", "87768.08", "87768.11", "87769.11", 
"87770.08", "87773.08", "87773.1", "87773.11", "87774.09", "87774.11", 
"87775.08", "87776.08", "87776.11", "87777.1", "87778.08", "87783.09", 
"88724.1", "88727.09", "111868.11", "111871.12", "112702.12", 
"112712.12", "112714.12", "120947.12", "121189.12", "121192.12", 
"121196.12", "1211931.12"), class = "factor"), sex = structure(c(3L, 
3L, 3L, 3L, 3L, 3L), .Label = c("F", "Fc", "M"), class = "factor"), 
    speed = c(0.921691675, 2.990097297, 2.137609076, 3.259383146, 
    8.173674567, 8.413534172), area = structure(c(3L, 3L, 3L, 
    3L, 3L, 3L), .Label = c("AA", "AM", "AR"), class = "factor"), 
    angulo = c(41.027, -43.41, 29.056, 18.241, -7.125, -4.702
    ), angle_rel = c(0.7160619, -0.7576522, 0.5071251, 0.3183724, 
    -0.1243479, -0.08206201), bat.depth = c(-45L, -397L, -32L, 
    -29L, -21L, -3L), dist = c(5.53015005, 17.94058378, 12.82565446, 
    19.55629887, 49.0420474, 50.48120503), angulo_modulo = c(41.027, 
    43.41, 29.056, 18.241, 7.125, 4.702), curva = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L), .Label = c("curva", "reta"), class = "factor")), row.names = 2:7, class = "data.frame")

PS: Sorry for my poor english, I hope you can understand my question xD

Upvotes: 1

Views: 6530

Answers (1)

stefan
stefan

Reputation: 124148

Not sure whether I got you right but maybe this what you are looking for:

  1. To get the scale of the secondary axis right you have to apply the inverse transformation on your data, i.e. as your are multiplying by 6 you have to divide angulo_modulo by 6 in the data.

  2. To get the two boxplots dodged I would suggest to use tidyr::pivot_longer so that your two variables become two categories of one variable which by default is named name while the values go to value. This way you can map value on y and name on color, alpha and fill. By default ggplot2 will give you two side-by-side boxplots per area.

library(ggplot2)
library(tidyr)
library(dplyr)

dados2 %>% 
  mutate(angulo_modulo = angulo_modulo / 6) %>% 
  pivot_longer(cols = c(speed, angulo_modulo)) %>% 
  mutate(name = factor(name, levels = c("speed", "angulo_modulo"))) %>% 
  ggplot(aes(x = area)) +
  geom_boxplot(aes(y = value, color = name, alpha = name, fill = name)) +
  scale_y_continuous(name = "speed (km/h)", sec.axis = sec_axis(~ . * 6, name = expression("turn angle (graus)"))) +
  scale_x_discrete(name = "Area") +
  scale_color_manual(values = c(angulo_modulo = "darkblue", speed = "#a50026")) +
  scale_alpha_manual(values = c(0.7, 1)) +
  theme_bw() +
  theme(plot.title = element_text(size = 14, family = "sans", face = "bold"),
        text = element_text(size = 12, family = "sans"),
        axis.title = element_text(face="bold"),
        axis.text.x=element_text(size = 11),
        legend.position = "bottom") +
  scale_fill_brewer(palette = "Accent")

Upvotes: 4

Related Questions