Announcement

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

  • Add number of observations table underneath a twoway graph

    Hello

    I am trying to produce a line graph (by group) which includes a table underneath with the number of observations in each of the groups. I would like this to be automated as much as possible to save me manually adding text to each of the graphs.

    So far I have managed to get the information on to the graph by adding a straight scatter graph & using the marker labels to show the information I want (see the attached graph using dummy data - in practice my sample size varies by arm/week).

    However, this text is still above the x-axis. Is there a way to get this table to show underneath the graph/axis? (like in the 2nd example attached from a journal). It also is a bit arbitrary to select where on the y-axis this data should show, so I wonder if I am missing something.

    This is the code I have so far (using a dataset from the Stata website):

    Code:
    set scheme white_tableau // installed from SSC (schemepack)
    
    * use & refine
    webuse pig.dta, clear
    gen group = id>24
    bys id (week): gen weight_change = weight - weight[1]
    lab def group 0 "Control" 1 "Intervention"
    lab val group group
    
    * collapse
    collapse (count) count=weight_change (median) med=weight_change (p25) p25=weight_change (p75) p75=weight_change, by(group week)
    
    * y-axis where data table should appear
    gen y0 = -5
    gen y1 = -7
    
    * graph (method 1)
    twoway (connected med week if group==0, color(red))                        ///
        (connected med week if group==1, color(midblue))                    ///
        (rcap p25 p75 week if group==0, color(red))                            ///
        (rcap p25 p75 week if group==1, color(midblue))                        ///
        (scatter y0 week if group==0, m(i) mlabel(count) mlabpos(0))        ///
        (scatter y1 week if group==1, m(i) mlabel(count) mlabpos(0)),        ///
        text(-5 -1 "Control:" -7 -1 "Intervention:", size(vsmall) place(e))    ///
        ytitle("Median weight change (g), IQR")                                ///
        xtitle("Week")                                                        ///
        ylabel(0(20)60)                                                        ///
        legend(order(1 "Control" 2 "Intervention"))

    Thank you for any help
    Bryony

    Click image for larger version

Name:	Graph.png
Views:	1
Size:	58.4 KB
ID:	1744230 Click image for larger version

Name:	Example.png
Views:	1
Size:	59.8 KB
ID:	1744231

  • #2
    See if the following thread helps: https://www.statalist.org/forums/for...pants-censored. If not and no one else responds, post back and I will have a look at your example.

    Comment


    • #3
      Hi Andrew - thanks for your reply. I've had a look at the thread & I can't seem to get it to apply. I can't use the addplot with the twoway graph & so when I specify my y-axis position, it still lowers the x-axis so that the text is above the axis.

      I did manage another work around but adding text to the graph instead. I build the text in a local before & then put these into the graph code (as in the code below).

      It seems to work, but it seems a little long for something I thought would be simple to do.


      Code:
      * code for creating the graph after the collapse command above:
      * create text for n table
      // starting value for x-axis line where text appears
      local x = -10
      foreach g in 0 1 {
          
          // x-axis value where n appears
          local x = `x'-2
      
          // generate empty local
          local text_g`g' ""
          
          // loop around weeks to add n for each label
          forvalues w = 1/9 {
              sum count if week==`w' & group==`g'
              local text_g`g' `text_g`g'' text(`x' `w' "`r(mean)'", size(vsmall))
          }
          
          // local for group name
          local vl: label group `g'
          local name_g`g' text(`x' -1 "`vl':", size(vsmall) placement(e))
      }
      
      * graph (method 1)
      twoway (connected med week if group==0, color(red))                        ///
          (connected med week if group==1, color(midblue))                    ///
          (rcap p25 p75 week if group==0, color(red))                            ///
          (rcap p25 p75 week if group==1, color(midblue)),                    ///
          `text_g0' `text_g1'                                                 ///
          `name_g0' `name_g1'                                                    ///
          ytitle("Median weight change (g), IQR")                                ///
          xtitle("Week")                                                        ///
          legend(order(1 "Control" 2 "Intervention"))                            ///
          graphregion(margin(b=7))
      Click image for larger version

Name:	Graph2.png
Views:	1
Size:	58.1 KB
ID:	1744345

      Comment


      • #4
        See the highlighted options below. BTW, -addplot()- is an option to call twoway for twoway-type graphs (that are not themselves twoway).

        Code:
        webuse pig.dta, clear
        gen group = id>24
        bys id (week): gen weight_change = weight - weight[1]
        lab def group 0 "Control" 1 "Intervention"
        lab val group group
        
        * collapse
        collapse (count) count=weight_change (median) med=weight_change (p25) p25=weight_change (p75) p75=weight_change, by(group week)
        
        * y-axis where data table should appear
        gen y0 = -5
        gen y1 = -7
        
        * graph (method 1)
        twoway (connected med week if group==0, color(red))                        ///
            (connected med week if group==1, color(midblue))                    ///
            (rcap p25 p75 week if group==0, color(red))                            ///
            (rcap p25 p75 week if group==1, color(midblue))                        ///
            (scatter y0 week if group==0, ms(none) mlabel(count) mlabpos(6) mlabgap(14))        ///
            (scatter y1 week if group==1, ms(none) mlabel(count) mlabpos(6) mlabgap(14)),        ///
            text(-19 -1 "Control:" -21 -1 "Intervention:", size(vsmall) place(e))    ///
            ytitle("Median weight change (g), IQR")  graphregion(margin(0 0 5 0)) ///
            xtitle("Week")                                                        ///
            ylabel(0(20)60)                                                        ///
            legend(order(1 "Control" 2 "Intervention"))
        Click image for larger version

Name:	Graph.png
Views:	1
Size:	51.6 KB
ID:	1744351

        Last edited by Andrew Musau; 23 Feb 2024, 07:22.

        Comment


        • #5
          That's fantastic - thank you for your help.

          Comment

          Working...
          X