1

I have a ggplot2 plot that is not working the way i want to..:) The first plot is showing the orginal plot. Bars illustrate each participants at different timepoints(online/offline). enter image description here

Next plot i have reorder/ or ranked the bars displaying lowest score first. As you can see, the lines is following the old structure and not following the ranked bars. enter image description here

the code for the ranking and plot:

delta.plot.indiv1 = delta.plot.indiv %>% 
  group_by(Learning) %>% 
  mutate(position = rank(+tot))


ggplot(delta.plot.indiv1,
       aes(x=Learning, y=tot, color=sub,group=sub))+
labs(title = "Distribution of online and offline learning", x = "", y = "Time(S/trial)")+
  scale_x_discrete(labels=c("online"="Online", "offline"="Offline"))+
  geom_hline(yintercept=0, size=.5)+
   scale_fill_viridis(discrete = TRUE) +
  geom_bar(aes(group=position),alpha=0.1, stat = "identity", position="dodge")+
   geom_line(aes(group=sub),position = position_dodge(width = 0.9)) +
  geom_point(aes(group = position), position = position_dodge(width = 0.9))+
  theme_classic()+
  theme(plot.title = element_text(hjust = 0.5, family = "serif",face="bold", colour="black", size = 12), 
        axis.text.x = element_text(family = "serif",face="bold", colour="black", size = 12),
        axis.title.y = element_text(angle = 90,vjust = 0.5, family = "serif", face="bold", colour="black", size = 12),
        legend.title = element_text(family = "serif", face="bold", size = 10),
        legend.text = element_text(color = "black", family = "serif", size=10, face="bold"))+
  facet_grid(.~age.group)+
  theme(legend.position="none")

If dataset is needed I can provide that?

Dataset:

dput(delta.plot.indiv1)
structure(list(sub = structure(c(2L, 3L, 4L, 5L, 6L, 7L, 8L, 
9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 
22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 
35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 
48L, 49L, 50L, 51L, 52L, 53L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 
61L, 62L, 63L, 64L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 
12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 
25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 
38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 
51L, 52L, 53L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 
64L), levels = c("", "01TIPP", "02TIPP", "03TIPP", "04TIPP", 
"05TIPP", "06TIPP", "07TIPP", "08TIPP", "09TIPP", "10TIPP", "11TIPP", 
"12TIPP", "13TIPP", "14TIPP", "15TIPP", "16TIPP", "17TIPP", "18TIPP", 
"19TIPP", "20TIPP", "21TIPP", "22TIPP", "23TIPP", "24TIPP", "25TIPP", 
"26TIPP", "27TIPP", "28TIPP", "29TIPP", "30TIPP", "31TIPP", "32TIPP", 
"33TIPP", "34TIPP", "35TIPP", "41TIPP", "42TIPP", "43TIPP", "44TIPP", 
"45TIPP", "46TIPP", "47TIPP", "48TIPP", "49TIPP", "50TIPP", "51TIPP", 
"52TIPP", "53TIPP", "54TIPP", "55TIPP", "56TIPP", "57TIPP", "58TIPP", 
"59TIPP", "60TIPP", "61TIPP", "62TIPP", "63TIPP", "64TIPP", "65TIPP", 
"66TIPP", "68TIPP", "69TIPP"), class = "factor"), age.group = structure(c(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, 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, 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), levels = c("senior", 
"u13"), class = "factor"), Learning = structure(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, 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, 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), levels = c("online", 
"offline", "total"), class = "factor"), tot = c(0.243, -0.2007, 
0.442399943, 0.1558, -0.0805, 0.3858, 0.183, 0.3005, 0.394, -0.0333, 
0.0831, 0.4231, 0.6312, 0.1811, 0.2035, 0.3559, 0.2471, 0.253, 
0.0859, 0.237, 0.0104, 0.391, 0.3872, 0, 0.386549962, 0.2772, 
0.2211, 0.0215999999999998, 0.0934999999999999, 0.5438, 0.2204, 
0.116449988, 0.123199975, 0.3537, 0.4956, 0.2818, 0.3722, 0.1575, 
0.467, 0.4341, 0.3663, 0.2735, 0.2831, 0.0981000000000001, 0.1648, 
0.3649, 0.242, 0.3213, 0.4375, 0.3231, 0.6152, 0.2207, -0.0631999999999999, 
0.125749994, 0.295400035, 0.336000013, 0.391049958, 0.420749986, 
0.209400022, 0.567149961, 0.588150025, 0.218700003, 0.100900018, 
0.2087, 0.187, -0.148150003, 0.1305, 0.4307, -0.1377, 0.0793999999999999, 
0.0974999999999999, -0.15799998, 0.3869, 0.5595, 0.0750000000000002, 
-0.345, 0.063799961, -0.013450019, -0.00435001900000009, -0.228900042, 
-0.0807000059999998, 0.146399988, 0.063300012, 0.0834499730000001, 
0.169649993, -0.12499993, 0.221549998, -0.211399925, 0.155400028, 
0.0641499620000001, 0.135849957, 0.271399994, -0.105500009, -0.0452500039999999, 
0.289299953, 0.116900051, 0.144499989, -0.172299992, 0.0716000299999999, 
-0.115149914, -0.170499966, -0.2222, -0.1189, -0.0132000000000001, 
-0.1756, -0.1147, -0.2183, 0.0641, -0.1536, 0.00309999999999988, 
-0.1162, -0.1341, 0.0628, -0.2751, 0.0910000480000002, 0.00639999999999996, 
0.217150056, -0.266399956, -0.100300014, -0.179900015, -0.0598499539999999, 
-0.128449976, -0.275499976, -0.282550013, 0.17720002, -0.0894499659999999
), position = c(29, 1, 56, 16, 2, 46, 20, 37, 51, 4, 8, 53, 63, 
19, 21, 42, 30, 31, 9, 27, 6, 49, 48, 5, 47, 33, 26, 7, 10, 59, 
24, 13, 14, 41, 58, 34, 45, 17, 57, 54, 44, 32, 35, 11, 18, 43, 
28, 38, 55, 39, 62, 25, 3, 15, 36, 40, 50, 52, 22, 60, 61, 23, 
12, 56, 55, 16, 48, 62, 17, 43, 46, 14, 61, 63, 42, 1, 38, 31, 
33, 6, 28, 51, 37, 44, 53, 20, 58, 9, 52, 40, 49, 59, 25, 30, 
60, 47, 50, 12, 41, 23, 13, 7, 21, 32, 11, 24, 8, 39, 15, 34, 
22, 18, 36, 4, 45, 35, 57, 5, 26, 10, 29, 19, 3, 2, 54, 27)), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -126L), groups = structure(list(
    Learning = structure(1:2, levels = c("online", "offline", 
    "total"), class = "factor"), .rows = structure(list(1:63, 
        64:126), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -2L), .drop = TRUE))

Best A

Expect that lines can be connected to the dots

August
  • 11
  • 2
  • Welcome to SO! From your images and your code I would guess that you messed up the grouping, i.e. you are mapping different variables on the `group` aes. And guessing further I would guess that simply doing `group=position` in `geom_line` will not fix that issue but you could give it a try. For more help it would indeed help if you provide [a minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) including a snippet of your data or some fake data shared via `dput()`. – stefan Mar 07 '23 at 13:39
  • Please provide enough code so others can better understand or reproduce the problem. – Community Mar 07 '23 at 14:09
  • Hi, I will provide the data in the Question above :) I have tried with group=position in geom_line but it result in lines at random placed. – August Mar 08 '23 at 05:40

1 Answers1

0

As I already mentioned in my comment your issue could not be fixed by the group aes. The reason is that on the one hand we want to dodge the lines by position as for the points and the bars but at the same time we want to group by sub to connect by subject.

Instead we have to manually dodge the lines, i.e. we have to manually compute the x positions for the lines. Basically this could be achieved using the formula:

mutate(position_line = as.numeric(factor(Learning)) + dodge_width * (position - n / 2) / n)

where n is the number of subjects per age.group.

library(dplyr)
library(ggplot2)
library(viridis)

dodge_width <- .9
pd <- position_dodge(width = dodge_width)
delta.plot.indiv1 <- delta.plot.indiv |> 
  group_by(age.group, Learning) |> 
  mutate(position = rank(+tot), n = n()) |> 
  ungroup() |> 
  mutate(position_line = as.numeric(factor(Learning)) + dodge_width * (position - n / 2) / n)

ggplot(
  delta.plot.indiv1,
  aes(x = Learning, y = tot, color = sub, group = position)
) +
  labs(title = "Distribution of online and offline learning", x = "", y = "Time(S/trial)") +
  scale_x_discrete(labels = c("online" = "Online", "offline" = "Offline")) +
  geom_hline(yintercept = 0, size = .5) +
  scale_fill_viridis(discrete = TRUE) +
  geom_bar(alpha = 0.1, stat = "identity", position = pd) +
  geom_line(aes(x = position_line, group = sub)) +
  geom_point(position = pd) +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, family = "serif", face = "bold", colour = "black", size = 12),
    axis.text.x = element_text(family = "serif", face = "bold", colour = "black", size = 12),
    axis.title.y = element_text(angle = 90, vjust = 0.5, family = "serif", face = "bold", colour = "black", size = 12),
    legend.title = element_text(family = "serif", face = "bold", size = 10),
    legend.text = element_text(color = "black", family = "serif", size = 10, face = "bold")
  ) +
  facet_grid(. ~ age.group) +
  theme(legend.position = "none")

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51
  • 1
    Wauw, thank you so much @stefan. That solved the problem and make sense in order to do it manual ! Very grateful:)) – August Mar 10 '23 at 11:31