Line Plot with standard deviation

Viewed 298

I want to create a line chart, with two lines that shows the standard deviation for each for each line. At the moment, I have a line chart, that shows the two lines. My Code is this, Categories is the name for the x-axes, Result 1/2 are the Results and SD 1/2 is the standard deviation.

categories <-c("Traditionsbewusst / Heimatverbunden","Bekanntheit
+ ","Jugendlich / Modern
+ ","Professionell
+ ","Sozial engagiert
+ ","Aufstrebend / Motiviert
+ ","Umwelt / Nachhaltigkeit
+ ","Sympathisch
+ ","Familienfreundlich
+ ","Mitreißend
+ ","Posetives Image
+ ","Teamgeist
+ ","Inovativ
+ ")


Result1<-c(2.34,1.76,2.66,2.85,2.45,2.66,2.64,2.89,2.61,2.80,2.94,2.72,2.82)
Result2<-c(2.08,1.29,2.41,2.39,2.11,2.08,2.34,2.25,2.19,2.24,2.58,2.19,2.42)

SD1<-c(0.89,0.93,0.85,0.92,0.78,0.86,0.86,1.01,0.83,0.86,0.92,0.90,0.97)
SD2<-c(0.96,0.71,0.80,0.85,0.89,1.00,0.76,0.94,0.87,0.93,0.94,0.95,0.85)

par(mar = c(15, 3, 3, 3))
plot(Result1,type = "b",main = "Profil Image",xlab = "",ylab = "Bewertung",axes =FALSE,ylim = c(1,4))
axis(1,at=1:13,labels = categories,las=2,cex.axis=0.8)
lines(Result2,type = "b")
axis(2)
2 Answers

StupidWolf already answered your question, but I want to show you an alternative approach for plotting your data using ggplot2, tidyr and dplyr. They are all included in the package tidyverse.

First we need to create an data.frame:

df <- data.frame(categories, Result1, Result2, SD1, SD2)
                            categories Result1 Result2  SD1  SD2
1  Traditionsbewusst / Heimatverbunden    2.34    2.08 0.89 0.96
2                          Bekanntheit    1.76    1.29 0.93 0.71
3                  Jugendlich / Modern    2.66    2.41 0.85 0.80
4                        Professionell    2.85    2.39 0.92 0.85
5                     Sozial engagiert    2.45    2.11 0.78 0.89

Now we need to tidy up the data a bit, bringing it into a "long" format:

df %<>% 
  pivot_longer(cols=starts_with("Result"), names_to="Group", names_prefix="Result", values_to="Result") %>%
  pivot_longer(cols=starts_with("SD"), names_to="SD_Group", names_prefix="SD", values_to="SD") %>%
  filter(Group == SD_Group) %>%
  select(-SD_Group)

# A tibble: 26 x 4
   categories                          Group Result    SD
   <chr>                               <chr>  <dbl> <dbl>
 1 Traditionsbewusst / Heimatverbunden 1       2.34  0.89
 2 Traditionsbewusst / Heimatverbunden 2       2.08  0.96
 3 Bekanntheit                         1       1.76  0.93
 4 Bekanntheit                         2       1.29  0.71
 5 Jugendlich / Modern                 1       2.66  0.85

Now there is a variable Group, that separates Result1, SD1 and Result2, SD2. The values of Result and SD are presented in the column Result and SD. Data in this kind of presentation is usally easier to be worked with.

Now we are using ggplot to create the plot. ggplot provides many possibilities for plotting data at the cost of a complex syntax.

ggplot(df, aes(x=categories, y=Result, group=Group, color=Group)) +
  geom_line() + 
  geom_errorbar(aes(ymin=Result-SD, ymax=Result+SD)) +
  geom_point() + 
  theme(axis.text.x = element_text(angle = 65, vjust = 1, hjust = 1), 
        plot.title = element_text(hjust = 0.5),
        strip.text.x = element_blank()) + 
  ylim(c(0,4.5)) +
  labs(title="Profil Image", 
       x=NULL, 
       y="Bewertung",
       color="Gruppe") +
  facet_wrap(~Group, labeller=labeller(Group=paste0("Gruppe ", 1:2)))

gives

ggplot_of_categories_vs_rating_per_group

You can use arrows, see this post too. If you put them on the same graph, it looks really bad:

par(mar = c(15, 3, 3, 3))
plot(Result1,type = "b",main = "Profil Image",xlab = "",ylab = "Bewertung",axes =FALSE,ylim = c(0,4))
arrows(x0=1:length(SD1), y0=Result1-SD1, x1=1:length(SD1),code=3,y1=Result1+SD1,angle=90, length=0.05)
arrows(x0=1:length(SD2), y0=Result2-SD2, x1=1:length(SD2),code=3,y1=Result2+SD2,angle=90, length=0.05)
axis(1,at=1:13,labels = categories,las=2,cex.axis=0.8)
lines(Result2,type = "b")
axis(2)

enter image description here

Maybe put them side by side:

par(mfrow=c(1,2))
par(mar = c(15, 3, 3, 3))
plot(Result1,type = "b",main = "Profil Image",xlab = "",ylab = "Bewertung",axes =FALSE,ylim = c(0,4))
arrows(x0=1:length(SD1), y0=Result1-SD1, x1=1:length(SD1),code=3,y1=Result1+SD1,angle=90, length=0.05)
axis(1,at=1:13,labels = categories,las=2,cex.axis=0.8)
axis(2)

plot(Result2,type = "b",main = "Profil Image",xlab = "",ylab = "Bewertung",axes =FALSE,ylim = c(0,4))
arrows(x0=1:length(SD2), y0=Result2-SD2, x1=1:length(SD2),code=3,y1=Result2+SD2,angle=90, length=0.05)
axis(1,at=1:13,labels = categories,las=2,cex.axis=0.8)
axis(2)

enter image description here

Related