how to plot two columns of data frame columns with ggplot and without melting

887 Views Asked by At

I created a dataframe which includes a set of coefficients with their standard deviations as shown below:

      x    co_crowd sd_co_crowd co_not_crowd sd_co_not_crowd
1  0.60  0.43012132   0.1747872    0.3966671       0.1687380
2  0.62  0.46063333   0.1773200    0.3377529       0.1660473
3  0.64  0.46269688   0.1828233    0.3298026       0.1611410
4  0.66  0.40083469   0.1859609    0.3821874       0.1579615
5  0.68  0.35852075   0.1875722    0.3772546       0.1565694
6  0.70  0.28980734   0.1910099    0.4147173       0.1547535
7  0.72  0.33115725   0.1995733    0.3605751       0.1499210
8  0.74  0.37740694   0.2050877    0.3499887       0.1471462
9  0.76  0.33312104   0.2065729    0.3349059       0.1463895
10 0.78  0.33023339   0.2087189    0.3309792       0.1444242
11 0.80  0.20648732   0.2226057    0.4126518       0.1408211
12 0.82  0.08671806   0.2333934    0.5076005       0.1374987
13 0.84  0.09258312   0.2418525    0.4890796       0.1356016
14 0.86  0.08282405   0.2712092    0.4910314       0.1318858
15 0.88  0.05364842   0.2880257    0.5179220       0.1296971
16 0.90 -0.09106470   0.3429453    0.5345661       0.1263504

What I want to do is to plot co_crowd column with its error bar (sd_co_crowd) and also co_not_crowd with its relevant error bar (sd_co_not_crowd) in a form of line plot with points on it. Originally, I wrote the code below for plotting:

plot(x, co_crowd, type="o", col="blue", ylim=c(-0.1,0.7), xlab="",ylab="")
lines(x, co_not_crowd, type="o", pch=22, lty=2, col="red", xlab="",ylab="")


title(main="Coeff results", col.main="red", font.main=4)
legend(0.6, 0.1, legend=c("non_crowd", "crowd"),col=c("red", "blue"), lty=1:2, cex=1.2)
grid(nx = NULL, ny = NULL, col = "lightgray", lty = "dotted")
title(xlab= "Thresholds")  
title(ylab= "Coefficients")  

and the result was in this form:

enter image description here

now I want to add an error bar to this plot; however, the function I found is geom_errorbar which is for ggplot and can't be used here. So, in order to use it, I have to use ggplot. now I am wondering how I can plot two columns of dataframe without melting in a form of line and dot? (like the one I originally plotted)

So at the end, what I want to have is something in this form: enter image description here

by using ggplot. (I plotted it with excel for demonstration purpose)

1

There are 1 best solutions below

2
On BEST ANSWER

I would suggest this approach. Just few thoughts, as non melted approach is required, you would need to add the variables in separated geoms. The advantage is that you have few variables. Also in order to show the legend, you can add the aesthetic element color inside aes() so that the legend is created and in the end you can change the color with scale_color_manual(). And about the error bar, the way I have built it is using value-sd but you could consider other approaches as using the mean and standard deviation. Here the code:

library(ggplot2)
#Code
ggplot(df,aes(x=x,y=co_crowd))+
  geom_line(aes(color='crowd'))+
  geom_point(aes(color='crowd'))+
  geom_errorbar(aes(ymin=co_crowd-sd_co_crowd,
                    ymax=co_crowd+sd_co_crowd,color='crowd'))+
  geom_line(aes(x=x,y=co_not_crowd,color='not_crowd'))+
  geom_point(aes(x=x,y=co_not_crowd,color='not_crowd'))+
  geom_errorbar(aes(ymin=co_not_crowd-sd_co_not_crowd,
                    ymax=co_not_crowd+sd_co_not_crowd,color='not_crowd'))+
  theme_bw()+
  theme(legend.position = 'top',
        axis.text = element_text(color='black',face='bold'),
        axis.title = element_text(color='black',face='bold'),
        legend.text = element_text(color='black',face='bold'),
        legend.title = element_text(color='black',face='bold'))+
  labs(color='Variable',y='')+
  scale_color_manual(values=c('red','blue'))

Output:

enter image description here

Some data used:

#Data
df <- structure(list(x = c(0.6, 0.62, 0.64, 0.66, 0.68, 0.7, 0.72, 
0.74, 0.76, 0.78, 0.8, 0.82, 0.84, 0.86, 0.88, 0.9), co_crowd = c(0.43012132, 
0.46063333, 0.46269688, 0.40083469, 0.35852075, 0.28980734, 0.33115725, 
0.37740694, 0.33312104, 0.33023339, 0.20648732, 0.08671806, 0.09258312, 
0.08282405, 0.05364842, -0.0910647), sd_co_crowd = c(0.1747872, 
0.17732, 0.1828233, 0.1859609, 0.1875722, 0.1910099, 0.1995733, 
0.2050877, 0.2065729, 0.2087189, 0.2226057, 0.2333934, 0.2418525, 
0.2712092, 0.2880257, 0.3429453), co_not_crowd = c(0.3966671, 
0.3377529, 0.3298026, 0.3821874, 0.3772546, 0.4147173, 0.3605751, 
0.3499887, 0.3349059, 0.3309792, 0.4126518, 0.5076005, 0.4890796, 
0.4910314, 0.517922, 0.5345661), sd_co_not_crowd = c(0.168738, 
0.1660473, 0.161141, 0.1579615, 0.1565694, 0.1547535, 0.149921, 
0.1471462, 0.1463895, 0.1444242, 0.1408211, 0.1374987, 0.1356016, 
0.1318858, 0.1296971, 0.1263504)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16"))

After that, you can adjust any additional detail if required about colors of other elements.