Announcement

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

  • Treatment Effect Visualization Help

    Hello Everyone,

    I am making a visualization for treatment effects that looks something like this:

    Click image for larger version

Name:	Screenshot 2022-05-26 233409.png
Views:	1
Size:	23.4 KB
ID:	1666459

    The code I used to make this is as follows (please note that I am using the Auto dataset from within Stata for this):

    Code:
    
    * Generating Sample Data
    * Requires a baseline variable, and a treatment variable (one group)
    sysuse auto, clear
    
    generate treat = 0 if _n <= _N/5
    replace treat = 1 if missing(treat)
    
    
    tab treat, gen(treatment)
    replace treatment1 = . if treatment1 != 1
    
    * Generating sample baseline price
    generate price1 = price - 3000, after(price)
    
    
    * Note:
    * NO need to edit from this point onwards unless you want to modify the look
    * of the visual and possibly change the way data is displayed or fix errors
    ********************************************************************************
    
    * Regression with first treatment arm
    quietly regress price treatment2 trunk, robust
    matrix A1 = r(table)'
    
        * Control mean figures
        matrix define C1a = J(1, 9, .)
        ci means price if treatment2 == 0
        matrix C1a[1,1] = r(mean)
        matrix C1a[1,5] = r(lb)
        matrix C1a[1,6] = r(ub)
        matrix colnames C1a = b e t pvalue ll ul df crit eform
        matrix rownames C1a = control
    
        matrix define C1b = J(1, 9, .)
        ci means price1 if treatment2 == 0
        matrix C1b[1,1] = r(mean)
        matrix C1b[1,5] = r(lb)
        matrix C1b[1,6] = r(ub)
        matrix colnames C1b = b e t pvalue ll ul df crit eform
        matrix rownames C1b = controlbase
    
        
    * Append Regression results with control mean    
    matrix G1 = A1\C1a\C1b
    
    * Generating column vector of 1 to denote treatment arm 1
    local rows1 : rowsof G1
    matrix T1 = J(`rows1', 1, 1)
    matrix colnames T1 = treatarm
    
    * Combining columnwise the regression results and treatment arm
    matrix combined = G1,T1
    
    matrix list combined
    
    ********************************************************************************
    * Saving matrix as a dataset
    
    * get original row names of matrix (and row count)
    local rownames : rowfullnames combined
    local c : word count `rownames'
    
    * get original column names of matrix and substitute out _cons
    local names : colfullnames combined
    local newnames : subinstr local names "_cons" "cons", word
    
    * rename columns of matrix
    matrix colnames combined = `newnames'
    
    * convert to dataset
    clear
    svmat combined, names(col)
    
    * add matrix row names to dataset
    gen rownames = ""
    forvalues i = 1/`c' {
        replace rownames = "`:word `i' of `rownames''" in `i'
    }
    order rownames
    
    ********************************************************************************
    
    * Plotting
    generate treatment = treatarm
    
    replace treatment = 1 if treatment == 1 & rownames == "controlbase"
    replace treatment = 5 if treatment == 1 & rownames == "control"
    
    replace treatment = 5 if treatment == 1 & rownames == "treatment2"
    
    * Generate full coefficient
    sort treatarm, stable
    
    by treatarm: generate srno = _n
    reshape wide rownames b se t pvalue ll ul df crit eform treatment, i(srno) j(treatarm)
    
    generate control1 = b1 if rownames1 == "control", after(b1)
    ereplace control1 = max(control1)
    
    
    replace b1 = b1 + control1 if rownames1 == "treatment2"
    replace ll1 = ll1 + control1 if rownames1 == "treatment2"
    replace ul1 = ul1 + control1 if rownames1 == "treatment2"
    
    
    * Intercept point calculation
    * Since our intervention point is X=3 on the horizontal axis, we need Y value
    * We will use Y = MX + C
    * First we need slope: M = (y2 - y1)/(x2 - x1)
    
    local X = 3
    
    local bl : display `=_N'
    local ctrl : display (`=_N' - 1)
    
    local M = (b1[`ctrl'] - b1[`bl']) / (treatment1[`ctrl'] - treatment1[`bl'])
    local C = b1[`ctrl'] - (`M' * treatment1[`ctrl'])
    local Y = (`M' * `X') + `C'
    
    local newobs : display `=_N' + 1
    set obs `newobs'
    
    replace treatment1 = `X' if _n == _N
    replace b1 = `Y' if _n == _N
    replace rownames1 = "intercept" if _n == _N
    
    
    * Plot
    
    if (b1[`ctrl'] > b1[`bl']) & (b1[`ctrl'] > b1[1]) {
        local min : display b1[`bl'] - abs(b1[`bl']*0.25)
        local max : display b1[`ctrl'] + abs(b1[`ctrl']*0.25)
        local textpos: display `min' + abs(b1[`bl']*(1/8))
    }
    else if (b1[`ctrl'] > b1[`bl']) & (b1[`ctrl'] < b1[1]) {
        local min : display b1[`bl'] - abs(b1[`bl']*0.25)
        local max : display b1[`ctrl'] + abs(b1[`ctrl']*0.25)
        local textpos: display `min' + abs(b1[`bl']*(1/8))    
    }
    else if (b1[`ctrl'] < b1[`bl']) & (b1[`ctrl'] > b1[1]) {
        local min : display b1[1] - abs(b1[1]*0.25)
        local max : display b1[`bl'] + abs(b1[`bl']*0.25)
        local textpos: display `min' + abs(b1[1]*(1/8))        
    }
    else {
        local min : display b1[`ctrl'] - abs(b1[`ctrl']*0.25)
        local max : display b1[`bl'] + abs(b1[`bl']*0.25)
        local textpos: display `min' + abs(b1[`ctrl']*(1/8))
    
    }
    
    
    local trt : display b1[1]
    local ctr : display b1[`ctrl']
    
    local teff : display round(abs(`ctr' - `trt'), .01)
    
    if `trt' > `ctr' {
    local val : display `trt' - abs(`teff'/2)
    }
    else {
    local val : display `trt' + abs(`teff'/2)    
    }
    
    * Text Box values
    local topb : display `textpos' + abs(`textpos'*0.05)
    local botb : display `textpos' - abs(`textpos'*0.05)
    
    
    #delimit ;
    twoway     (connected b1 treatment1 if inlist(rownames1, "treatment2", "intercept"), ms(i))
            (connected b1 treatment1 if inlist(rownames1, "control", "controlbase"), ms(i))
            (scatteri `trt' 5.1 `ctr' 5.1, recast(line) lcolor(gs4))
            (scatteri `ctr' 5.05 `ctr' 5.1, recast(line) lcolor(gs4))
            (scatteri `trt' 5.05 `trt' 5.1, recast(line) lcolor(gs4))
            (scatteri `min' 1 `max' 1, recast(line) lcolor(dkgreen%40))
            (scatteri `min' 3 `max' 3, recast(line) lcolor(gs3%50) lpattern(dash))
            (scatteri `min' 5 `max' 5, recast(line) lcolor(red%40))
            (scatteri `val' 5.35 "`teff'", ms(i) mlabpos(0))
            (scatteri `botb' 0.7 `botb' 1.3 `topb' 1.3 `topb' 0.7, recast(area) color(white) lwidth(0.2) lcolor(dkgreen%40))
            (scatteri `textpos' 1 "Baseline", ms(i) mlabpos(0) mlabsize(2.25))
            (scatteri `botb' 2.7 `botb' 3.3 `topb' 3.3 `topb' 2.7, recast(area) color(white) lwidth(0.2) lcolor(gs3%50))
            (scatteri `textpos' 3 "Intervention", ms(i) mlabpos(0) mlabsize(2.25))
            (scatteri `botb' 4.7 `botb' 5.3 `topb' 5.3 `topb' 4.7, recast(area) color(white) lwidth(0.2) lcolor(red%40))
            (scatteri `textpos' 5 "Endline", ms(i) mlabpos(0) mlabsize(2.25))
            ,
            title("{bf} Treatment Effect Visualization",  pos(11) margin(b+3 t=-1) size(*.6)) 
            subtitle("Single group automation of graph using sysuse auto",  pos(11) margin(b+6 t=-3 l=1.75) size(*.6)) 
            xlabel(none)
            xtitle("")
            ylabel(none)
            ytitle("")
            yscale(range(`min' `max') off)
            legend(order(2 1) label(1 "Treatment") label(2 "Control") size(2.25))
            scheme(white_tableau)
            
            ;
    #delimit cr
    Probably not the most efficient code i must say lol but does the job!

    Coming to my question. There are text boxes generated (highlighted in red within the code block) at the bottom of the visualization that mark 'baseline' 'intervention' and 'endline' that neatly encapsulate the text with adequate margins. An issue i faced with visualization is that if the minimum value starts getting close to 0, the text box size starts to vertically grow too large.

    Is there a way of fixing the text box size in a manner that it maintains its look as seen above?

    The text box below is an example of how it looks like if lowest point gets close to 0:

    Click image for larger version

Name:	Screenshot 2022-05-27 002619.png
Views:	1
Size:	18.7 KB
ID:	1666460

    I hope the example has adequate information. Please let me know if clarity is required.
    Also, if there is any way to improve on the code, then that help will be very much appreciated!


  • #2
    I don't understand- what is the treatment effect you've calculated, or more specifically, what's the design you used to calculate your treatment effect?

    I also can't follow the problem from the figure very well. What is the issue with the figure you've presented? What would you like to see that the figure doesn't currently present?

    Comment


    • #3
      The treatment effect is just an example, its not really of significance as it is just arbitrarily developed. The problem is that the text box formed at the bottom of the visual increase in vertical height if the minimum value on the plot starts getting closer to zero as illustrated in the second visual. I would like to have some workaround where i can maintain the text box sizes as seen in picture 1 of the post.

      I hope this helps

      Comment


      • #4
        You can restrict the size of the box using an -if- condition. Use a percentage of the y-range instead of a fixed value as I do below.

        Code:
        * Generating Sample Data
        * Requires a baseline variable, and a treatment variable (one group)
        sysuse auto, clear
        
        generate treat = 0 if _n <= _N/5
        replace treat = 1 if missing(treat)
        
        
        tab treat, gen(treatment)
        replace treatment1 = . if treatment1 != 1
        
        * Generating sample baseline price
        generate price1 = price - 1000, after(price)
        
        
        * Note:
        * NO need to edit from this point onwards unless you want to modify the look
        * of the visual and possibly change the way data is displayed or fix errors
        ********************************************************************************
        
        * Regression with first treatment arm
        quietly regress price treatment2 trunk, robust
        matrix A1 = r(table)'
        
            * Control mean figures
            matrix define C1a = J(1, 9, .)
            ci means price if treatment2 == 0
            matrix C1a[1,1] = r(mean)
            matrix C1a[1,5] = r(lb)
            matrix C1a[1,6] = r(ub)
            matrix colnames C1a = b e t pvalue ll ul df crit eform
            matrix rownames C1a = control
        
            matrix define C1b = J(1, 9, .)
            ci means price1 if treatment2 == 0
            matrix C1b[1,1] = r(mean)
            matrix C1b[1,5] = r(lb)
            matrix C1b[1,6] = r(ub)
            matrix colnames C1b = b e t pvalue ll ul df crit eform
            matrix rownames C1b = controlbase
        
            
        * Append Regression results with control mean    
        matrix G1 = A1\C1a\C1b
        
        * Generating column vector of 1 to denote treatment arm 1
        local rows1 : rowsof G1
        matrix T1 = J(`rows1', 1, 1)
        matrix colnames T1 = treatarm
        
        * Combining columnwise the regression results and treatment arm
        matrix combined = G1,T1
        
        matrix list combined
        
        ********************************************************************************
        * Saving matrix as a dataset
        
        * get original row names of matrix (and row count)
        local rownames : rowfullnames combined
        local c : word count `rownames'
        
        * get original column names of matrix and substitute out _cons
        local names : colfullnames combined
        local newnames : subinstr local names "_cons" "cons", word
        
        * rename columns of matrix
        matrix colnames combined = `newnames'
        
        * convert to dataset
        clear
        svmat combined, names(col)
        
        * add matrix row names to dataset
        gen rownames = ""
        forvalues i = 1/`c' {
            replace rownames = "`:word `i' of `rownames''" in `i'
        }
        order rownames
        
        ********************************************************************************
        
        * Plotting
        generate treatment = treatarm
        
        replace treatment = 1 if treatment == 1 & rownames == "controlbase"
        replace treatment = 5 if treatment == 1 & rownames == "control"
        
        replace treatment = 5 if treatment == 1 & rownames == "treatment2"
        
        * Generate full coefficient
        sort treatarm, stable
        
        by treatarm: generate srno = _n
        reshape wide rownames b se t pvalue ll ul df crit eform treatment, i(srno) j(treatarm)
        
        generate control1 = b1 if rownames1 == "control", after(b1)
        ereplace control1 = max(control1)
        
        
        replace b1 = b1 + control1 if rownames1 == "treatment2"
        replace ll1 = ll1 + control1 if rownames1 == "treatment2"
        replace ul1 = ul1 + control1 if rownames1 == "treatment2"
        
        
        * Intercept point calculation
        * Since our intervention point is X=3 on the horizontal axis, we need Y value
        * We will use Y = MX + C
        * First we need slope: M = (y2 - y1)/(x2 - x1)
        
        local X = 3
        
        local bl : display `=_N'
        local ctrl : display (`=_N' - 1)
        
        local M = (b1[`ctrl'] - b1[`bl']) / (treatment1[`ctrl'] - treatment1[`bl'])
        local C = b1[`ctrl'] - (`M' * treatment1[`ctrl'])
        local Y = (`M' * `X') + `C'
        
        local newobs : display `=_N' + 1
        set obs `newobs'
        
        replace treatment1 = `X' if _n == _N
        replace b1 = `Y' if _n == _N
        replace rownames1 = "intercept" if _n == _N
        
        
        * Plot
        
        if (b1[`ctrl'] > b1[`bl']) & (b1[`ctrl'] > b1[1]) {
            local min : display b1[`bl'] - abs(b1[`bl']*0.25)
            local max : display b1[`ctrl'] + abs(b1[`ctrl']*0.25)
            local textpos: display `min' + abs(b1[`bl']*(1/8))
        }
        else if (b1[`ctrl'] > b1[`bl']) & (b1[`ctrl'] < b1[1]) {
            local min : display b1[`bl'] - abs(b1[`bl']*0.25)
            local max : display b1[`ctrl'] + abs(b1[`ctrl']*0.25)
            local textpos: display `min' + abs(b1[`bl']*(1/8))    
        }
        else if (b1[`ctrl'] < b1[`bl']) & (b1[`ctrl'] > b1[1]) {
            local min : display b1[1] - abs(b1[1]*0.25)
            local max : display b1[`bl'] + abs(b1[`bl']*0.25)
            local textpos: display `min' + abs(b1[1]*(1/8))        
        }
        else {
            local min : display b1[`ctrl'] - abs(b1[`ctrl']*0.25)
            local max : display b1[`bl'] + abs(b1[`bl']*0.25)
            local textpos: display `min' + abs(b1[`ctrl']*(1/8))
        
        }
        
        
        local trt : display b1[1]
        local ctr : display b1[`ctrl']
        
        local teff : display round(abs(`ctr' - `trt'), .01)
        
        if `trt' > `ctr' {
        local val : display `trt' - abs(`teff'/2)
        }
        else {
        local val : display `trt' + abs(`teff'/2)    
        }
        
        * Text Box values
        local topb : display `textpos' + abs(`textpos'*0.05)
        local botb : display `textpos' - abs(`textpos'*0.05)
        local diff= `topb'- `botb'
        if `diff'>365{
            local topb = `topb'-`diff'+(365/2)
            local botb= `botb' +`diff'-(365/2)
        }
        
        
        #delimit ;
        twoway     (connected b1 treatment1 if inlist(rownames1, "treatment2", "intercept"), ms(i))
                (connected b1 treatment1 if inlist(rownames1, "control", "controlbase"), ms(i))
                (scatteri `trt' 5.1 `ctr' 5.1, recast(line) lcolor(gs4))
                (scatteri `ctr' 5.05 `ctr' 5.1, recast(line) lcolor(gs4))
                (scatteri `trt' 5.05 `trt' 5.1, recast(line) lcolor(gs4))
                (scatteri `min' 1 `max' 1, recast(line) lcolor(dkgreen%40))
                (scatteri `min' 3 `max' 3, recast(line) lcolor(gs3%50) lpattern(dash))
                (scatteri `min' 5 `max' 5, recast(line) lcolor(red%40))
                (scatteri `val' 5.35 "`teff'", ms(i) mlabpos(0))
                (scatteri `botb' 0.7 `botb' 1.3 `topb' 1.3 `topb' 0.7, recast(area) color(white) lwidth(0.2) lcolor(dkgreen%40))
                (scatteri `textpos' 1 "Baseline", ms(i) mlabpos(0) mlabsize(2.25))
                (scatteri `botb' 2.7 `botb' 3.3 `topb' 3.3 `topb' 2.7, recast(area) color(white) lwidth(0.2) lcolor(gs3%50))
                (scatteri `textpos' 3 "Intervention", ms(i) mlabpos(0) mlabsize(2.25))
                (scatteri `botb' 4.7 `botb' 5.3 `topb' 5.3 `topb' 4.7, recast(area) color(white) lwidth(0.2) lcolor(red%40))
                (scatteri `textpos' 5 "Endline", ms(i) mlabpos(0) mlabsize(2.25))
                ,
                title("{bf} Treatment Effect Visualization",  pos(11) margin(b+3 t=-1) size(*.6))
                subtitle("Single group automation of graph using sysuse auto",  pos(11) margin(b+6 t=-3 l=1.75) size(*.6))
                xlabel(none)
                xtitle("")
                ylabel(none)
                ytitle("")
                yscale(range(`min' `max') off)
                legend(order(2 1) label(1 "Treatment") label(2 "Control") size(2.25))
                scheme(white_tableau)
                
                ;
        #delimit cr
        Last edited by Andrew Musau; 26 May 2022, 15:11.

        Comment


        • #5
          Andrew Musau Thank you so much for the solution, interesting approach!. However, it seems that when the lowest value starts going a lot further down (for example when we subtract 5000 from price to generate price1), the box starts to shrink into the text. Also, I feel that your solution might not work generally on different scales (from what i think). Any thoughts?

          Comment


          • #6
            Originally posted by Fahad Mirza View Post
            Andrew MusauHowever, it seems that when the lowest value starts going a lot further down (for example when we subtract 5000 from price to generate price1), the box starts to shrink into the text.
            EDITED: You have defined only a condition for greater than. You need to also define a condition for less than.


            Also, I feel that your solution might not work generally on different scales (from what i think). Any thoughts?
            That is why I told you to use a percentage of the y-range instead of a fixed value. I can illustrate later when I have time.
            Last edited by Andrew Musau; 27 May 2022, 03:56.

            Comment


            • #7
              This fixes the height at 3% of the y-range and thus ensures that the size is invariant to the treatment effect.

              Code:
              * Generating Sample Data
              * Requires a baseline variable, and a treatment variable (one group)
              sysuse auto, clear
              
              generate treat = 0 if _n <= _N/5
              replace treat = 1 if missing(treat)
              
              
              tab treat, gen(treatment)
              replace treatment1 = . if treatment1 != 1
              
              * Generating sample baseline price
              generate price1 = price - 1000, after(price)
              
              
              * Note:
              * NO need to edit from this point onwards unless you want to modify the look
              * of the visual and possibly change the way data is displayed or fix errors
              ********************************************************************************
              
              * Regression with first treatment arm
              quietly regress price treatment2 trunk, robust
              matrix A1 = r(table)'
              
                  * Control mean figures
                  matrix define C1a = J(1, 9, .)
                  ci means price if treatment2 == 0
                  matrix C1a[1,1] = r(mean)
                  matrix C1a[1,5] = r(lb)
                  matrix C1a[1,6] = r(ub)
                  matrix colnames C1a = b e t pvalue ll ul df crit eform
                  matrix rownames C1a = control
              
                  matrix define C1b = J(1, 9, .)
                  ci means price1 if treatment2 == 0
                  matrix C1b[1,1] = r(mean)
                  matrix C1b[1,5] = r(lb)
                  matrix C1b[1,6] = r(ub)
                  matrix colnames C1b = b e t pvalue ll ul df crit eform
                  matrix rownames C1b = controlbase
              
                  
              * Append Regression results with control mean    
              matrix G1 = A1\C1a\C1b
              
              * Generating column vector of 1 to denote treatment arm 1
              local rows1 : rowsof G1
              matrix T1 = J(`rows1', 1, 1)
              matrix colnames T1 = treatarm
              
              * Combining columnwise the regression results and treatment arm
              matrix combined = G1,T1
              
              matrix list combined
              
              ********************************************************************************
              * Saving matrix as a dataset
              
              * get original row names of matrix (and row count)
              local rownames : rowfullnames combined
              local c : word count `rownames'
              
              * get original column names of matrix and substitute out _cons
              local names : colfullnames combined
              local newnames : subinstr local names "_cons" "cons", word
              
              * rename columns of matrix
              matrix colnames combined = `newnames'
              
              * convert to dataset
              clear
              svmat combined, names(col)
              
              * add matrix row names to dataset
              gen rownames = ""
              forvalues i = 1/`c' {
                  replace rownames = "`:word `i' of `rownames''" in `i'
              }
              order rownames
              
              ********************************************************************************
              
              * Plotting
              generate treatment = treatarm
              
              replace treatment = 1 if treatment == 1 & rownames == "controlbase"
              replace treatment = 5 if treatment == 1 & rownames == "control"
              
              replace treatment = 5 if treatment == 1 & rownames == "treatment2"
              
              * Generate full coefficient
              sort treatarm, stable
              
              by treatarm: generate srno = _n
              reshape wide rownames b se t pvalue ll ul df crit eform treatment, i(srno) j(treatarm)
              
              generate control1 = b1 if rownames1 == "control", after(b1)
              ereplace control1 = max(control1)
              
              
              replace b1 = b1 + control1 if rownames1 == "treatment2"
              replace ll1 = ll1 + control1 if rownames1 == "treatment2"
              replace ul1 = ul1 + control1 if rownames1 == "treatment2"
              
              
              * Intercept point calculation
              * Since our intervention point is X=3 on the horizontal axis, we need Y value
              * We will use Y = MX + C
              * First we need slope: M = (y2 - y1)/(x2 - x1)
              
              local X = 3
              
              local bl : display `=_N'
              local ctrl : display (`=_N' - 1)
              
              local M = (b1[`ctrl'] - b1[`bl']) / (treatment1[`ctrl'] - treatment1[`bl'])
              local C = b1[`ctrl'] - (`M' * treatment1[`ctrl'])
              local Y = (`M' * `X') + `C'
              
              local newobs : display `=_N' + 1
              set obs `newobs'
              
              replace treatment1 = `X' if _n == _N
              replace b1 = `Y' if _n == _N
              replace rownames1 = "intercept" if _n == _N
              
              
              * Plot
              
              if (b1[`ctrl'] > b1[`bl']) & (b1[`ctrl'] > b1[1]) {
                  local min : display b1[`bl'] - abs(b1[`bl']*0.25)
                  local max : display b1[`ctrl'] + abs(b1[`ctrl']*0.25)
                  local textpos: display `min' + abs(b1[`bl']*(1/8))
              }
              else if (b1[`ctrl'] > b1[`bl']) & (b1[`ctrl'] < b1[1]) {
                  local min : display b1[`bl'] - abs(b1[`bl']*0.25)
                  local max : display b1[`ctrl'] + abs(b1[`ctrl']*0.25)
                  local textpos: display `min' + abs(b1[`bl']*(1/8))    
              }
              else if (b1[`ctrl'] < b1[`bl']) & (b1[`ctrl'] > b1[1]) {
                  local min : display b1[1] - abs(b1[1]*0.25)
                  local max : display b1[`bl'] + abs(b1[`bl']*0.25)
                  local textpos: display `min' + abs(b1[1]*(1/8))        
              }
              else {
                  local min : display b1[`ctrl'] - abs(b1[`ctrl']*0.25)
                  local max : display b1[`bl'] + abs(b1[`bl']*0.25)
                  local textpos: display `min' + abs(b1[`ctrl']*(1/8))
              
              }
              
              
              local trt : display b1[1]
              local ctr : display b1[`ctrl']
              
              local teff : display round(abs(`ctr' - `trt'), .01)
              
              if `trt' > `ctr' {
              local val : display `trt' - abs(`teff'/2)
              }
              else {
              local val : display `trt' + abs(`teff'/2)    
              }
              
              * Text Box values
              local scale = `max'-`min'
              local topb : display `textpos' + abs(`scale'*0.03)
              local botb : display `textpos' - abs(`scale'*0.03)
              
              
              #delimit ;
              twoway     (connected b1 treatment1 if inlist(rownames1, "treatment2", "intercept"), ms(i))
                      (connected b1 treatment1 if inlist(rownames1, "control", "controlbase"), ms(i))
                      (scatteri `trt' 5.1 `ctr' 5.1, recast(line) lcolor(gs4))
                      (scatteri `ctr' 5.05 `ctr' 5.1, recast(line) lcolor(gs4))
                      (scatteri `trt' 5.05 `trt' 5.1, recast(line) lcolor(gs4))
                      (scatteri `min' 1 `max' 1, recast(line) lcolor(dkgreen%40))
                      (scatteri `min' 3 `max' 3, recast(line) lcolor(gs3%50) lpattern(dash))
                      (scatteri `min' 5 `max' 5, recast(line) lcolor(red%40))
                      (scatteri `val' 5.35 "`teff'", ms(i) mlabpos(0))
                      (scatteri `botb' 0.7 `botb' 1.3 `topb' 1.3 `topb' 0.7, recast(area) color(white) lwidth(0.2) lcolor(dkgreen%40))
                      (scatteri `textpos' 1 "Baseline", ms(i) mlabpos(0) mlabsize(2.25))
                      (scatteri `botb' 2.7 `botb' 3.3 `topb' 3.3 `topb' 2.7, recast(area) color(white) lwidth(0.2) lcolor(gs3%50))
                      (scatteri `textpos' 3 "Intervention", ms(i) mlabpos(0) mlabsize(2.25))
                      (scatteri `botb' 4.7 `botb' 5.3 `topb' 5.3 `topb' 4.7, recast(area) color(white) lwidth(0.2) lcolor(red%40))
                      (scatteri `textpos' 5 "Endline", ms(i) mlabpos(0) mlabsize(2.25))
                      ,
                      title("{bf} Treatment Effect Visualization",  pos(11) margin(b+3 t=-1) size(*.6))
                      subtitle("Single group automation of graph using sysuse auto",  pos(11) margin(b+6 t=-3 l=1.75) size(*.6))
                      xlabel(none)
                      xtitle("")
                      ylabel(none)
                      ytitle("")
                      yscale(range(`min' `max') off)
                      legend(order(2 1) label(1 "Treatment") label(2 "Control") size(2.25))
                      scheme(white_tableau)
                      
                      ;
              #delimit cr

              Comment


              • #8
                Thank you so much Andrew Musau this looks great! Now thinking of expanding it to multiple treatment arms and different scenarios! Do you think I should look at some portion of this code with some more efficient technique? if so, can you recommend some readings or website to look into?

                Comment


                • #9
                  Do you want to generalize it into a command? If so, you may want to look at the ado files of some popular community-contributed graphic commands and see how they are set up.

                  Code:
                  viewsource commandname.ado

                  I cannot give specific comments as it will take me time to study the code in detail, but it does not look overly excessive and does the job, so it looks good from my layman's eyes.

                  Comment

                  Working...
                  X