Announcement

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

  • Plot mean and standard deviation by time, for two groups on the same figure

    I am trying to plot the time series of mean and standard deviation of a variable, for 2 different groups in the same figure. For a single group, meansdplot works well:
    Code:
    webuse abdata, clear
    meansdplot wage year if ind == 4
    However, I don't know how to overlay two groups in the same figure. The following code does not work:
    Code:
    twoway (meansdplot wage year if ind == 4) (meansdplot wage year if ind == 7)
    If meansdplot does not work for this purpose, is there a good approach in Stata?
    Last edited by David Tsu; 09 Jun 2021, 23:22.

  • #2
    meansdplot is community-contributed command from https://stats.idre.ucla.edu/stat/stata/ado/analysis as you are asked to explain (FAQ Advice #12).

    It is a standalone program and not a twoway type, so the wanted syntax is indeed illegal.

    You wouldn't want superimposed plots any way, because this type of plot needs different groups to be offset horizontally if you are to avoid a tangled mess. The following isn't intended to reproduce the command, but more to show you can build up your own kind of plot from first principles.

    Code:
    webuse abdata, clear
    
    egen mean = mean(wage), by(ind year)
    egen sd = sd(wage), by(ind year)
    
    egen tag = tag(ind year)
    
    gen year2 = cond(ind == 4, year - 0.1, year + 0.1)
    
    gen upper = mean + sd 
    gen lower = mean - sd 
    set scheme s1color 
    
    twoway rcap upper lower year2 if tag  & ind == 4, lc(red) || scatter mean year2 if tag & ind == 4, mc(red) ///
    || rcap upper lower year2 if tag & ind == 7, lc(blue) || scatter mean year2 if tag & ind == 7, mc(blue) ///
    legend(order(2 "4" 4 "7")) xtitle("") xla(1976/1984) ytitle(Mean and SD of wage (units))

    Comment


    • #3
      Originally posted by Nick Cox View Post
      meansdplot is community-contributed command from https://stats.idre.ucla.edu/stat/stata/ado/analysis as you are asked to explain (FAQ Advice #12).

      It is a standalone program and not a twoway type, so the wanted syntax is indeed illegal.

      You wouldn't want superimposed plots any way, because this type of plot needs different groups to be offset horizontally if you are to avoid a tangled mess. The following isn't intended to reproduce the command, but more to show you can build up your own kind of plot from first principles.

      Code:
      webuse abdata, clear
      
      egen mean = mean(wage), by(ind year)
      egen sd = sd(wage), by(ind year)
      
      egen tag = tag(ind year)
      
      gen year2 = cond(ind == 4, year - 0.1, year + 0.1)
      
      gen upper = mean + sd
      gen lower = mean - sd
      set scheme s1color
      
      twoway rcap upper lower year2 if tag & ind == 4, lc(red) || scatter mean year2 if tag & ind == 4, mc(red) ///
      || rcap upper lower year2 if tag & ind == 7, lc(blue) || scatter mean year2 if tag & ind == 7, mc(blue) ///
      legend(order(2 "4" 4 "7")) xtitle("") xla(1976/1984) ytitle(Mean and SD of wage (units))
      Thanks, this looks good!

      I find out that combining this with rarea can get close to what meansdplot generates.

      Last question: what is the purpose of "tag" in your code?
      Last edited by David Tsu; 10 Jun 2021, 13:52.

      Comment


      • #4
        So that each mean, etc., is plotted just once, not as many times as there are observations.

        Comment


        • #5
          There is another easier way to plot this graph.You can use the the command -lgraph-(SSC).
          Code:
          webuse abdata, clear
          keep if inlist(ind,4,7)
          lgraph wage year ind,err(sd) lop(recast(scatter))
          Attached Files
          Best regards.

          Raymond Zhang
          Stata 17.0,MP

          Comment


          • #6
            Code:
            webuse abdata, clear
            gen year2 = cond(ind == 4, year - 0.05, year + 0.05)
            lgraph wage year2 ind if inlist(ind,4,7),err(sd) lop(recast(scatter))
            Attached Files
            Best regards.

            Raymond Zhang
            Stata 17.0,MP

            Comment


            • #7
              Raymond Zhang: Thank for posting the last entry. I get the following graph by running this command:
              webuse abdata, clear
              lgraph wage year ind if inlist(ind,1,2,3),err(sd) lop(recast(scatter))
              Graph.gph
              May you please suggest how to distance each of the three bars along x-axis?
              Thanks and regards, Bilal

              Comment


              • #8
                #2 is already an answer to #7 with easy modifications to the code.



                Code:
                webuse abdata, clear
                
                egen mean = mean(wage), by(ind year)
                egen sd = sd(wage), by(ind year)
                
                egen tag = tag(ind year)
                
                gen year2 = year + 0.15 * (ind - 2)
                
                gen upper = mean + sd 
                gen lower = mean - sd 
                set scheme s1color 
                
                twoway rcap upper lower year2 if tag  & ind == 1, lc(red) || scatter mean year2 if tag & ind == 1, mc(red) ms(S) ///
                || rcap upper lower year2 if tag & ind == 2, lc(black) || scatter mean year2 if tag & ind == 2, mc(black) ///
                || rcap upper lower year2 if tag & ind == 3, lc(blue) || scatter mean year2 if tag & ind == 3, mc(blue) ms(T) ///
                legend(order(2 "1" 4 "2" 6 "3") row(1)) xtitle("") xla(1976/1984) ytitle(Mean and SD of wage (units)) ///
                xli(1976.5/1983.5, lc(gs8) lw(thin)) yla(, ang(h))
                Click image for larger version

Name:	abdata.png
Views:	1
Size:	25.1 KB
ID:	1643413


                Comment


                • #9
                  Originally posted by Raymond Zhang View Post
                  There is another easier way to plot this graph.You can use the the command -lgraph-(SSC).
                  Code:
                  webuse abdata, clear
                  keep if inlist(ind,4,7)
                  lgraph wage year ind,err(sd) lop(recast(scatter))
                  @Raymond Zhang
                  Thank you for that code. I found it so helpful.
                  Is there any way to add a connecting line between the means as in the photo?
                  Thank you.

                  Attached Files

                  Comment

                  Working...
                  X