2017-03-10 10 views
9

Próbuję utworzyć wykres liniowy i punktowy z listami błędów. Ma różne czynniki, jednak niektóre czynniki mają tylko jedną wartość. Dowiedziałem się, że jeśli użyję position_dodge, jeden z jednego współczynnika wartości ma znacznie szerszy pasek błędów w porównaniu do innych słupków błędów na wykresach. W jakiś sposób position_dodge ma wpływ na szerokość na pasku błędów. Nie znalazłem nikogo, kto miałby ten sam problem wcześniej, więc mam nadzieję, że ktoś może mi pomóc.ggplot2 position_dodge wpływa na szerokość paska błędów

Dane manekin:

require(ggplot2) 

x <- c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,3,3,5) 
y <- c(3,5,6,3,5,3,5,6,2,6,3,7,3,6,2,1,5,8,7) 
se <- x*0.2 
treatment <- c("A", "B","C", "D","A", "B","C", "D","A", "B","C", "D","A", "B","C", "D","E", "F", "G") 
data <- data.frame(x, y, se ,treatment) 
data$treatment <- as.factor(data$treatment) 

Pierwsza działka bez position_dodge - wszystko jest w porządku

# Without position dodge 
myplot <- ggplot(data, aes(x=x, y=y, group= treatment, fill = treatment, colour = treatment)) + 
    geom_line(stat="identity", size = 1) + 
    geom_point(stat="identity", size = 3, shape = 21) + 
    geom_errorbar(aes(ymin = y-se, ymax = y+se), width = 0.2) 

myplot 

plot without position_dodge

Teraz działka z pozycji unik:

# With position dodge 
myplot <- ggplot(data, aes(x=x, y=y, group= treatment, fill = treatment, colour = treatment)) + 
    geom_line(stat="identity", size = 1, position=position_dodge(width=0.2)) + 
    geom_point(stat="identity", size = 3, shape = 21, position=position_dodge(width=0.2)) + 
    geom_errorbar(aes(ymin = y-se, ymax = y+se), width = 0.2, position=position_dodge(width=0.2)) 

myplot 

Plot with position_dodge

Jak widać pasek błędu po prawej stronie ma znacznie większą szerokość w porównaniu do innych pasków błędów. Jest tak prawdopodobnie dlatego, że nie ma nakładających się zmiennych x dla tego punktu, a paski błędów mogą mieć normalny rozmiar. Nadal chciałbym wiedzieć, w jaki sposób mogę uzyskać paski błędów o tej samej szerokości.

+0

Może istotną kwestią: https://github.com/tidyverse/ggplot2/issues/1068 – zx8754

+0

Tak pewnie, jeśli spojrzeć na drugim wykresie punkty dla x = 3 mają również mniejszy pasek błędów. Jest tak prawdopodobnie dlatego, że szerokość paska błędów zależy od liczby grup. – Marinka

+0

Tak, przestrzeń jest dzielona przez liczbę punktów, a linia pozioma staje się krótsza. Rozwiązaniem może być ręczne dodge, na przykład 'x = 1' będzie dla 4 punktów,' x = c (1, 1.02, 1.04, 1.06) ', a następnie usuń opcję dodge. – zx8754

Odpowiedz

4

Jak @aosmith sugeruje, poprawka do tego celu jest skala szerokość paska błędów do liczby punktów z tego x. Jednak nie trzeba tego robić ręcznie. Poniżej używam dplyr, aby utworzyć nową kolumnę w data.frame w oparciu o liczbę punktów w tym x. Usunąłem także odwzorowania group i fill, ponieważ żadne z nich nie jest tu potrzebne (pod warunkiem, że kształt zostanie zmieniony na wersję wypełnionego koła pokolorowaną przez colour zamiast fill). Na koniec, aby uniknąć powtórzeń, zdefiniowałem raz position, a następnie użyłem zmiennej dla każdego geom.

library(dplyr) 
data <- data %>% 
    group_by(x) %>% 
    mutate(
    width = 0.1 * n() 
) 

pos <- position_dodge(width = 0.2) 
myplot <- 
    ggplot(data, 
     aes(
      x = x, 
      y = y, 
      colour = treatment, 
      width = width 
     )) + 
    geom_line(size = 1, position = pos) + 
    geom_point(size = 3, shape = 16, position = pos) + 
    geom_errorbar(aes(ymin = y - se, ymax = y + se), position = pos) 

myplot 

Final image

+0

Dzięki za odpowiedź, to rozwiązuje problem. – Marinka

1

Nieco niewygodne obejście, z którego korzystałem w przeszłości, to ręczne ustawienie szerokości każdego paska błędów za pomocą width wewnątrz aes. Liczba wartości w każdej grupie mówi, jak skalować każdy pasek błędów.

Na przykład, jeśli mam grupę z jedną wartością i grupą z 3 wartościami, grupa 3 width musi być 3 razy większa niż grupa 1 width.

Twoja sprawa jest znacznie bardziej skomplikowana, ponieważ masz grupę 1, grupę 6 i 3 grupy po 4. Możesz zacząć od ustalenia, jaka dobra szerokość jest dla pojedynczej grupy. Wybrałem .1. Tak więc grupa 6 musi być szeroka, a grupa 4 musi być szeroka w zakresie od .4.

Następnie lewą stroną jest ustalenie kolejności rysowania linii w celu uzyskania szerokości. Jest to łatwiejsze w prostszych sytuacjach.

kod działki:

ggplot(data, aes(x = x, y = y, group = treatment, fill = treatment, colour = treatment)) + 
    geom_line(stat = "identity", size = 1, position = position_dodge(width = 0.2)) + 
    geom_point(stat = "identity", size = 3, shape = 21, position = position_dodge(width = 0.2)) + 
    geom_errorbar(aes(ymin = y-se, ymax = y+se, 
        width = c(rep(.4, 8), rep(.6, 4), rep(.4, 4), .6, .6, .1)), 
       position = position_dodge(width = 0.2)) 

enter image description here

+0

Dzięki za odpowiedź, przyjąłem odpowiedź Nicka Kennedy'ego, ponieważ przyszedł z automatycznym rozwiązaniem. – Marinka