Search code examples
rplotggplot2lattice

Plot lines with their standard deviation on different x axis


In the following example, I want have zone on y axis, then plot D1 with its standard deviation (shading) D1sd on x axis. Next, I want to add D1b and its standard deviation on the second x axis. My second question is that, is it possible to plot the second set of data D2 in a panel next to first one. I'm thinking of the way spplot puts the panels next to each other. Thanks!

zone    D1           D1sd         D1b        D1bsd    D2            D2sd        D2b      D2bsd
-10 6.018198819 1.353674355 0.820238734 0.299921523 6.149905542 1.559112995 0.71903318  0.281436916
-9  6.016694189 1.348320178 0.790463895 0.320471326 6.225247218 1.810133214 0.690944285 0.291123921
-8  6.075920068 1.268199241 0.792396958 0.295767298 6.452827975 1.890055573 0.698130383 0.285354803
-7  6.014926533 1.15754388  0.826652396 0.269340472 6.364786271 1.677836628 0.748784125 0.262342978
-6  5.934024155 1.097224151 0.876312952 0.287715603 6.167672962 1.558124318 0.755995918 0.265152681
-5  6.180879693 1.115373166 0.911045374 0.302416557 6.429580579 1.485044161 0.783518016 0.255475422
-4  6.215761357 1.287465467 0.930981232 0.302896699 6.579955644 1.388358072 0.810873074 0.234479504
-3  6.191414137 1.297136068 0.859521028 0.301839757 6.72533907  1.383269712 0.786424272 0.242793151
-2  6.249558839 1.484243431 0.870789671 0.315339266 6.738830636 1.39348093  0.822833797 0.28853238
-1  6.279693424 1.462642241 0.890051094 0.313090388 6.665698185 1.272444414 0.849884276 0.309606843
0   6.389352438 1.653046732 0.911295197 0.332748249 6.623842834 1.3384852   0.860175975 0.311888845
1   6.421109477 1.954238381 0.917046385 0.349039084 6.633736605 1.627187751 0.880706612 0.346350393
2   6.187522396 1.994178951 0.881417644 0.38571426  6.422238767 1.685610306 0.875399565 0.351651773
3   5.975654953 2.180870669 0.871365681 0.444535385 6.245207747 1.925609129 0.915266481 0.424662193
4   5.681784682 2.182018258 0.846469896 0.38550673  6.004553419 1.947533306 0.890484046 0.404342645
5   5.550390285 2.189799132 0.834608476 0.340348644 5.831848009 1.849502381 0.887486532 0.387460845
6   5.382758749 2.460409982 0.832118248 0.360057614 5.810419947 2.06423957  0.954814407 0.38078381
7   4.819027419 2.643911373 0.78895866  0.38043413  5.42194855  2.259929373 0.935858628 0.37891625
8   3.782918423 2.584426217 0.643611576 0.335647266 4.418220284 2.186679796 0.790979174 0.364691895
9   3.064023314 2.528951519 0.496242154 0.294101493 3.64670387  2.091471213 0.592464821 0.341064247
10  2.62392179  2.707531426 0.380282732 0.249942178 3.159422995 2.392110771 0.452474888 0.334645666

Solution

  • Load in data

    dat <- read.table(text = "zone    D1           D1sd         D1b        D1bsd    D2            D2sd        D2b      D2bsd
    -10 6.018198819 1.353674355 0.820238734 0.299921523 6.149905542 1.559112995 0.71903318  0.281436916
    -9  6.016694189 1.348320178 0.790463895 0.320471326 6.225247218 1.810133214 0.690944285 0.291123921
    -8  6.075920068 1.268199241 0.792396958 0.295767298 6.452827975 1.890055573 0.698130383 0.285354803
    -7  6.014926533 1.15754388  0.826652396 0.269340472 6.364786271 1.677836628 0.748784125 0.262342978
    -6  5.934024155 1.097224151 0.876312952 0.287715603 6.167672962 1.558124318 0.755995918 0.265152681
    -5  6.180879693 1.115373166 0.911045374 0.302416557 6.429580579 1.485044161 0.783518016 0.255475422
    -4  6.215761357 1.287465467 0.930981232 0.302896699 6.579955644 1.388358072 0.810873074 0.234479504
    -3  6.191414137 1.297136068 0.859521028 0.301839757 6.72533907  1.383269712 0.786424272 0.242793151
    -2  6.249558839 1.484243431 0.870789671 0.315339266 6.738830636 1.39348093  0.822833797 0.28853238
    -1  6.279693424 1.462642241 0.890051094 0.313090388 6.665698185 1.272444414 0.849884276 0.309606843
    0   6.389352438 1.653046732 0.911295197 0.332748249 6.623842834 1.3384852   0.860175975 0.311888845
    1   6.421109477 1.954238381 0.917046385 0.349039084 6.633736605 1.627187751 0.880706612 0.346350393
    2   6.187522396 1.994178951 0.881417644 0.38571426  6.422238767 1.685610306 0.875399565 0.351651773
    3   5.975654953 2.180870669 0.871365681 0.444535385 6.245207747 1.925609129 0.915266481 0.424662193
    4   5.681784682 2.182018258 0.846469896 0.38550673  6.004553419 1.947533306 0.890484046 0.404342645
    5   5.550390285 2.189799132 0.834608476 0.340348644 5.831848009 1.849502381 0.887486532 0.387460845
    6   5.382758749 2.460409982 0.832118248 0.360057614 5.810419947 2.06423957  0.954814407 0.38078381
    7   4.819027419 2.643911373 0.78895866  0.38043413  5.42194855  2.259929373 0.935858628 0.37891625
    8   3.782918423 2.584426217 0.643611576 0.335647266 4.418220284 2.186679796 0.790979174 0.364691895
    9   3.064023314 2.528951519 0.496242154 0.294101493 3.64670387  2.091471213 0.592464821 0.341064247
    10  2.62392179  2.707531426 0.380282732 0.249942178 3.159422995 2.392110771 0.452474888 0.334645666", header = T)
    

    First simple solution

    A first attempt. This first way is the 'normal' way of doing this. Normally we could flip x and y with coord_flip(), but that doesn't work with facets and free scales, unfortunately.

    library(ggplot2)
    dat2 <- data.frame(D = rep(c("D1", "D1b", "D2", "D2b"), each = nrow(dat)),
                       group = rep(c('1', '2'), each = nrow(dat) * 2),
                       zone = dat$zone,
                       value = unlist(dat[c(2, 4, 6, 8)]),
                       SD = unlist(dat[c(3, 5, 7, 9)]))
    
    ggplot(dat2, aes(zone, value, ymin = value - SD, ymax = value + SD, fill = group)) + 
      geom_point() + geom_line() + geom_ribbon(alpha = 0.2) +
      facet_wrap(~D, scales = 'free') +
      theme_bw()
    

    enter image description here

    A solution with flipped axes

    You can actually get flipped axes when you manually draw the polygons. This code is hardly pretty, but you should get the idea.

    polydat <- data.frame(D = rep(c("D1", "D1b", "D2", "D2b"), each = nrow(dat) * 2),
                          value = c(dat$D1 - dat$D1sd, rev(dat$D1 + dat$D1sd),
                                    dat$D1b - dat$D1bsd, rev(dat$D1b + dat$D1bsd),
                                    dat$D2 - dat$D2sd, rev(dat$D2 + dat$D2sd),
                                    dat$D2b - dat$D2bsd, rev(dat$D2b + dat$D2bsd)),
                          zone = c(dat$zone, rev(dat$zone)),
                          group = rep(c('1', '2'), each = nrow(dat) * 4))
    
    ggplot(dat2, aes(value, zone, fill = group)) +
      geom_point() + geom_path() +
      geom_polygon(data = polydat, alpha = 0.2) +
      facet_wrap(~D, scales = 'free') +
      theme_bw()
    

    enter image description here

    One way of getting this into two plots is to normalize the data into a common x-axis first (using scale for example).