Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to plot my data using twoway

    Dear Stata list:

    My data look like this:

    Code:
    clear
    input id y start end ylb yub
    1 2.0 0 1 1.9 2.1
    2 2.3 1 2 2.2 2.4
    3 2.1 2 3 2.0 2.2
    4 2.4 3 4 2.3 2.5
    end
    I.e. I have one variable y and its confidence intervals ylb and yub observed in different time periods for which I have a starting and end time.

    I would like to create a figure with time on the x-axis and y on the yaxis, kind of like this:

    Code:
    twoway (line y start, connect(J))
    Click image for larger version

Name:	Graph.png
Views:	1
Size:	8.4 KB
ID:	1469483

    There are two problems with this graph, though:

    1) I don't want the vertical lines
    2) It only goes to three on the x-axis, yet it should go to 4

    The third problem: I would like to add a shaded area around it denoting the confidence interval.

    Is there a simple solution to this?

    Thanks for your consideration
    Joe



  • #2
    I am not especially clear what your desired graph looks like. Here are two suggestions, one more orthodox in my experience than the other. It helps here that the default bar width is 1. Occasionally for cosmetic purposes, bars that almost touch appeal a little more than bars that do touch, even if the bins or intervals touch.

    Code:
    clear
    input id y start end ylb yub
    1 2.0 0 1 1.9 2.1
    2 2.3 1 2 2.2 2.4
    3 2.1 2 3 2.0 2.2
    4 2.4 3 4 2.3 2.5
    end
    
    gen when = (start + end)/2 
    set scheme s1color 
    local opts xtitle(time) ytitle(y) yla(, ang(h)) xla(0/4, grid glc(gs12)) legend(off) 
    local opts `opts' plotregion(margin(l 0 r 0)) 
    
    scatter y when || rcap ylb yub when, `opts' name(g1, replace) 
    
    twoway rbar ylb yub when, bcolor(gs12) || pcspike y start y end, `opts' name(g2, replace)
    Click image for larger version

Name:	ci_interval_1.png
Views:	1
Size:	15.4 KB
ID:	1469508


    Click image for larger version

Name:	ci_interval_2.png
Views:	1
Size:	14.9 KB
ID:	1469509

    Comment


    • #3
      This should get you started.

      Code:
      twoway (rarea ylb yub start) (line y start)
      Note that you can stack more than one figure with twoway, this can be very handy. The first, -rarea- gives you the shaded portion for the confidence bounds and the second the line. As for the X axis only going to three, I think you'll find that the start variable you use for the x-axis only goes to 3, the end variable goes to three, but starts at 1.

      Edit: Crossed with #2 which is obviously more extensive
      Last edited by Danial Hoepfner; 08 Nov 2018, 11:53.

      Comment


      • #4
        Dear Nick, thanks, this is amazing. I was interested exactly in a solution like g2. One hopefully minor thing still:

        It seems like the solution is only working because start and end are always one unit apart. Is there a way to generate a figure like g2 when the data e.g. look like this:

        Code:
        clear
        input id y start end ylb yub
        1 2.0 0 10 1.9 2.1
        2 2.3 10 20 2.2 2.4
        3 2.1 20 30 2.0 2.2
        4 2.4 30 40 2.3 2.5
        end
        Thanks so much again!
        Joe

        Comment


        • #5
          It's the same solution except that your barwidth() argument must be explicit as barwidth(10) -- and your axis labels will be different.

          Comment


          • #6
            Great, thanks!

            Comment


            • #7
              But what if the width of the bars varies, as in

              Code:
              clear input id y start end ylb yub
              1 2.0 0 15 1.9 2.1
              2 2.3 15 20 2.2 2.4
              3 2.1 20 32 2.0 2.2
              4 2.4 32 40 2.3 2.5
              end

              Comment


              • #8
                There are probably other ways to do this, but this one works. It could be automated. At present writing specific code is about as easy (difficult) as writing more general code.

                Why not tell us your real problem straight away?

                Code:
                clear 
                input id y start end ylb yub
                1 2.0 0 15 1.9 2.1
                2 2.3 15 20 2.2 2.4
                3 2.1 20 32 2.0 2.2
                4 2.4 32 40 2.3 2.5
                end
                
                sort end 
                set scheme s1color 
                gen when = (start + end) / 2 
                levelsof start, local(levels) 
                local opts xtitle(time) ytitle(y) yla(, ang(h)) xla(`levels' 40, grid glc(gs12)) legend(off) 
                local opts `opts' plotregion(margin(l 0 r 0)) 
                
                twoway rbar ylb yub when in 1, bcolor(gs12) barw(15) || ///
                rbar ylb yub when in 2, bcolor(gs12) barw(5) || ///
                rbar ylb yub when in 3, bcolor(gs12) barw(12) || ///
                rbar ylb yub when in 4, bcolor(gs12) barw(8) || ///
                || pcspike y start y end, `opts' name(g3, replace)

                Comment


                • #9
                  Dear Nick, I am sorry, I wanted to provide a simple example and wasn't able to foresee that it would be too simple for the solutions available.

                  In reality, my data set is a bit messier, with more overlaps in time, and much bigger, and needs some form of stratifying (as in using by()) at some point, thus I would think I need to automatize the process.

                  Right now, my solution is thanks to your help

                  Code:
                  clear
                  input id y start end ylb yub
                  1 2.0 0 15 1.9 2.1
                  2 2.3 15 20 2.2 2.4
                  3 2.1 20 32 2.0 2.2
                  4 2.4 32 40 2.3 2.5
                  5 2.6  8  9 2.3 2.9
                  6 2.6 33 34 2.5 2.7
                  7 2.3 35 37 2.1 2.4
                  end
                  
                  gen when = (start + end)/2
                  
                  list
                  set scheme s1color
                  local opts xtitle(time) ytitle(y) yla(, ang(h)) xla(0 (10) 40, grid glc(gs12)) legend(off)
                  local opts `opts' plotregion(margin(l 0 r 0))
                  
                  scatter y when || rcap ylb yub when, `opts' name(g1, replace)
                  
                  twoway (pcspike ylb start ylb end, lcolor(gs8)) ///
                         (pcspike yub start yub end, lcolor(gs8)) ///
                         (pcspike y   start   y end, lwidth(*2)), `opts' name(g2, replace)
                  Where I have given up on the idea of shaded areas, but as you can see this isn't working too perfect e.g. for id == 7. If you could give me a pointer as to how to automatize the process to come up with a solution for bringing shaded areas in, I'd be even more grateful.

                  All the best
                  Joe

                  Comment


                  • #10
                    I wouldn't give up completely on shaded areas as you can use transparency.


                    Code:
                    clear
                    input id y start end ylb yub
                    1 2.0 0 15 1.9 2.1
                    2 2.3 15 20 2.2 2.4
                    3 2.1 20 32 2.0 2.2
                    4 2.4 32 40 2.3 2.5
                    5 2.6  8  9 2.3 2.9
                    6 2.6 33 34 2.5 2.7
                    7 2.3 35 37 2.1 2.4
                    end
                    
                    sort end 
                    set scheme s1color 
                    gen when = (start + end) / 2 
                    levelsof start, local(starts) 
                    levelsof end, local(ends) 
                    local levels : list starts | ends 
                    
                    local opts xtitle(time) ytitle(y) yla(, ang(h)) xla(`levels', ang(v) grid glc(gs12)) legend(off) 
                    local opts `opts' plotregion(margin(l 0 r 0)) 
                    
                    local call 
                    
                    forval i = 1/7 { 
                        local w = end[`i'] - start[`i'] 
                        local call `call' rbar ylb yub when in `i', bfc(gs14%50) blc(gs8) barw(`w') || 
                    }
                    
                    twoway `call' /// 
                    pcspike y start y end, `opts' name(g3, replace)
                    Click image for larger version

Name:	bars_spikes.png
Views:	1
Size:	17.7 KB
ID:	1469636

                    Comment


                    • #11
                      Thanks, I will see how that works out for me!

                      Comment

                      Working...
                      X