Search code examples
graphstata

Combining graphs with common y axis


I have 4 graphs that provide mean and error bars of the same variable (content_knowledge) over different descriptive variables. Since they all share a common y axis, I want to create a combination of the 4 graphs such that I have one graph with only 1 y axis displayed.

The code used to create the 4 graphs and combination is as follows:

foreach var in Location Induction CPD Gender {
    
    preserve
    
drop if unique_teach_id==""

statsby mean_ck=r(mean) upper=r(ub) lower=r(lb), by(`var') clear : ci mean content_knowledge 
format mean_ck %9.3g

twoway (bar mean_ck `var', barwidth(0.3)) ///
   (rcap lower upper `var') ///
   (scatter mean_ck `var', msymbol(none) mlabel(mean_ck) mlabposition(1)), ///
   legend(off) title("`var'") saving(`var'_ck, replace) ///
   ylabel(0(10)55) xla(minmax,valuelabel) xtitle("") ytitle("")
       
  restore

}

grc1leg Location_ck.gph Induction_ck.gph CPD_ck.gph Gender_ck.gph , ///
title("Content Knowledge of Teachers") ycommon imargin(2 2 0 2) ///
graphregion(margin(l=22 r=22)) name(sk_combine) 

This yields this graph here

I tried the grc1leg command with specifying row(1) which looks like follows:

grc1leg Location_ck.gph Induction_ck.gph CPD_ck.gph Gender_ck.gph , ///
title("Content Knowledge of Teachers") row(1) iscale(1)

This yields the graph here

So, is there a way to combine the graphs like in picture 2 but with only one common y axis and an extended graph space with the two options for location, Induction, CPD, and Gender displayed on an extended x axis?

Thanks


Solution

  • There is no data example here to make the question a reproducible example.

    Here is some fake data and one way to do it. For means all close to 50% bar charts just waste space.

    * faking data 
    clear 
    set seed 2803 
    set obs 500
    gen content_knowledge = 100 * runiform() 
    
    foreach var in Location Induction CPD Gender {
        gen `var' = runiformint(0,1) 
        label values `var' `var'
    }
    
    label def Location 0 urban 1 rural
    label def Induction 0 no 1 yes
    label def CPD 0 no 1 yes 
    label def Gender 0 male 1 female 
    
    * start analysis 
    foreach var in Location Induction CPD Gender {    
         
    statsby mean_ck=r(mean) upper=r(ub) lower=r(lb), by(`var') saving(`var', replace) : ci mean content_knowledge 
    
    } 
    
    * ad hoc code 
    use Location, clear 
    append using Induction CPD Gender 
    
    gen xgroup = ceil(_n/2)
    label def xgroup 1 Location 2 Induction 3 CPD 4 Gender 
    label val xgroup xgroup 
     
    gen xaxis = xgroup + _n - 1  
    label def xaxis 1 "`: label (Location) 0'", add 
    label def xaxis 2 "`: label (Location) 1'", add 
    label def xaxis 4 "`: label (Induction) 0'", add 
    label def xaxis 5 "`: label (Induction) 1'", add 
    label def xaxis 7 "`: label (CPD) 0'", add 
    label def xaxis 8 "`: label (CPD) 1'", add 
    label def xaxis 10 "`: label (Gender) 0'", add 
    label def xaxis 11 "`: label (Gender) 1'", add 
    label val xaxis xaxis 
    
    drop Location Induction CPD Gender 
    list 
    
    scatter mean_ck xaxis || rcap lower upper xaxis, xla(1/2 4/5 7/8 10/11, valuelabel noticks) ///
    xmla(1.5 "Location" 4.5 "Induction" 7.5 "CPD" 10.5 "Gender", tlength(*5) tlc(none) labsize(medium)) ///
    xsc(r(0.5 11.5)) xtitle("") legend(off) title(Content Knowledge of Teachers) 
    

    enter image description here