Announcement

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

  • Aligning x-axes with graph combine

    Hi Statalist,

    Using 'graph combine' I have combined four graphs. The graphs depict physiological data (oxygen saturation, heart rate, sleep stage, and body position) simultaneously recorded over one night. For ease with interpretation, all the times on the x-axes must align vertically. I have used 'xcommon', which I assume scales the x-axes with a common range. However, the x-axes of the graphs still do not align, as the label sizes of the y-axes differ.

    How can I combine the four graphs so that the x-axes perfectly align, and not just have a common range?

    Thanks so much, as always.

    Generate example data (thought this would be easier than 'dataex').
    Code:
    clear
    insobs 100
    egen datetime = seq()
    gen spo2 = runiformint(80,100)
    gen hr = runiformint(50,110)
    gen ss = runiformint(0,4)
    gen bp = runiformint(0,6)
    Draw the four graphs and combine them. This is the original code, except I made some changes to accommodate the example data.
    Code:
    twoway ///
        (line spo2 datetime, lcolor("18 22 70%100") lwidth(vthin) xaxis(1) cmissing(n)), ///
        yscale(range(60 100)) ///
        ytitle("SpO2 (%)", axis(1) size(small)) /// xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
        graphregion(lwidth(none) ilwidth(none) lcolor(none) fcolor(white)) ///
        plotregion(fcolor(white) lcolor(white) lwidth(none) ilwidth(none) margin(zero)) ///
        xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
        ylabel(60(10)100, angle(horizontal)) ///
        yline(88, lpattern(shortdash) lwidth(vthin) lcolor("255 20 66")) ///
        xtitle(, axis(1) color(%0) size(zero)) ///
        legend(off) ///
        xsize(7.09) ///   
        ysize(1.15) ///
        nodraw ///
        name("oxygen_graph", replace)
    
    twoway ///
        (line hr datetime, lcolor("18 22 70%100") lwidth(vthin) xaxis(1) cmissing(n)), ///
        ytitle("Heart rate (bpm)", axis(1) size(small)) ///xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
        graphregion(lwidth(none) ilwidth(none) fcolor(white) lcolor(white)) ///
        plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(zero)) ///
        xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
        ylabel(, angle(horizontal)) ///
        xtitle(, axis(1) color(%0) size(zero)) ///
        legend(off) ///
        xsize(7.09) ///   
        ysize(1.15) ///
        nodraw ///
        name("hr_graph", replace)
        
    twoway ///
        (area ss datetime, fcolor("18 22 70%100") lwidth(none) base(0)), ///
        yscale(reverse) ///
        ytitle("Sleep stage", axis(1) size(small)) ///xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
        graphregion(lwidth(none) lcolor(none) ilwidth(none) fcolor(white)) ///
        plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(zero)) ///
        xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
        ylabel(0.5 "W" 1.5 "R" 2.5 "L" 3.5 "D", noticks nogrid angle(horizontal)) ///
        xtitle(, axis(1) color(%0) size(zero)) ///
        legend(off) ///
        xsize(7.09) ///   
        ysize(3.15) ///
        nodraw ///
        name("hypnogram_graph", replace)
    
    twoway ///
        (area bp datetime, fcolor("255 20 66%100") lwidth(none) base(0)) ///
        ,yscale(range(0(1)7) reverse) ///
        ytitle("Body position", axis(1) size(small)) ///xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
        graphregion(lwidth(none) lcolor(none) ilwidth(none) fcolor(white)) ///
        plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(zero)) ///
        xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
        ylabel(0.5 "in motion" 1.5 "upright" 2.5 "inclined" 3.5 "supine" 4.5 "left side" 5.5 "right side" 6.5 "prone", noticks nogrid angle(horizontal)) ///
        xtitle(, axis(1) color(%0) size(zero)) ///
        legend(off) ///
        xsize(7.09) ///   
        ysize(3.15) ///
        nodraw ///
        name("bodyposition_graph", replace)
        
    graph combine ///
        oxygen_graph hr_graph hypnogram_graph bodyposition_graph, ///
        xcommon ///
        cols(1) ///
        graphregion(fcolor(white) lcolor(white) lwidth(none) ilwidth(none) margin(zero)) ///
        plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(vsmall)) ///
        imargin(zero) ///
        name(oxygen_hr_hypnogram, replace)


  • #2
    You've put your finger on the problem. xcommon can only go so far -- but either gives up, or at least doesn't work well, if the axis labels are quite different lengths.

    As a general strategy I note the device at https://www.stata-journal.com/articl...article=gr0085 -- at the same your preference for different kinds of graphs for different variables would make that not much of a solution.

    Comment


    • #3
      Thanks Nick. xcommon does not work even if the y-axis labels have any different lengths at all. From what I have seen they must have the exact same length.

      I solved the issue by adding an invisible y-axis label on all four graphs. I set the colour of this label 'white', which in these graphs means it does not show. I had to play around a bit with the label size, to make sure there is no overlap between the invisible label and the other labels. With this, the four graphs have a common longest label-size, and will thus all align when using 'graph combine'. I simply added the following line after "ylabel" in the twoway code (just make sure "95" is changed to a value on the y-axis which does not have a label:

      Code:
      ylab(95 "in motion", notick add custom labcolor(white)) ///
      The code then looks as follows:
      Code:
      clear
      insobs 100
      egen datetime = seq()
      gen spo2 = runiformint(80,100)
      gen hr = runiformint(50,110)
      gen ss = runiformint(0,4)
      gen bp = runiformint(0,6)
      
      twoway ///
          (line spo2 datetime, lcolor("18 22 70%100") lwidth(vthin) xaxis(1) cmissing(n)), ///
          yscale(range(60 100)) ///
          ytitle("SpO2 (%)", axis(1) size(small)) /// xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
          graphregion(lwidth(none) ilwidth(none) lcolor(none) fcolor(white)) ///
          plotregion(fcolor(white) lcolor(white) lwidth(none) ilwidth(none) margin(zero)) ///
          xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
          ylabel(60(10)100, angle(horizontal) labsize(small)) ///
          ylab(95 "in motion", notick add custom labcolor(white)) ///
          yline(88, lpattern(shortdash) lwidth(vthin) lcolor("255 20 66")) ///
          xtitle(, axis(1) color(%0) size(zero)) ///
          legend(off) ///
          xsize(7.09) ///   
          ysize(1.15) ///
          nodraw ///
          name("oxygen_graph", replace)
      
      twoway ///
          (line hr datetime, lcolor("18 22 70%100") lwidth(vthin) xaxis(1) cmissing(n)), ///
          ytitle("Heart rate (bpm)", axis(1) size(small)) ///xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
          graphregion(lwidth(none) ilwidth(none) fcolor(white) lcolor(white)) ///
          plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(zero)) ///
          xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
          ylabel(, angle(horizontal) labsize(small)) ///
          ylab(90 "in motion", notick add custom labcolor(white)) ///
          xtitle(, axis(1) color(%0) size(zero)) ///
          legend(off) ///
          xsize(7.09) ///   
          ysize(1.15) ///
          nodraw ///
          name("hr_graph", replace)
          
      twoway ///
          (area ss datetime, fcolor("18 22 70%100") lwidth(none) base(0)), ///
          yscale(reverse) ///
          ytitle("Sleep stage", axis(1) size(small)) ///xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
          graphregion(lwidth(none) lcolor(none) ilwidth(none) fcolor(white)) ///
          plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(zero)) ///
          xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
          ylabel(0.5 "Wake" 1.5 "REM" 2.5 "Light" 3.5 "Deep", noticks nogrid angle(horizontal) labsize(small)) ///
          ylab(1 "in motion", notick add custom labcolor(white)) ///
          xtitle(, axis(1) color(%0) size(zero)) ///
          legend(off) ///
          xsize(7.09) ///   
          ysize(3.15) ///
          nodraw ///
          name("hypnogram_graph", replace)
      
      twoway ///
          (area bp datetime, fcolor("255 20 66%100") lwidth(none) base(0)) ///
          ,yscale(range(0(1)7) reverse) ///
          ytitle("Body position", axis(1) size(small)) ///xtitle(, axis(2) color(%0) size(zero)) ///xtitle(, axis(1) color(%0) size(zero)) ///
          graphregion(lwidth(none) lcolor(none) ilwidth(none) fcolor(white)) ///
          plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(zero)) ///
          xlabel(0 (10) 100, grid axis(1) format(%tcHH:MM) labsize(small) labcolor(black%100)) ///    
          ylabel(0.5 "in motion" 1.5 "upright" 2.5 "inclined" 3.5 "supine" 4.5 "left side" 5.5 "right side" 6.5 "prone", noticks nogrid angle(horizontal) labsize(small)) ///
          ylab(1 "in motion", notick add custom labcolor(white)) ///
          xtitle(, axis(1) color(%0) size(zero)) ///
          legend(off) ///
          xsize(7.09) ///   
          ysize(3.15) ///
          nodraw ///
          name("bodyposition_graph", replace)
          
      graph combine ///
          oxygen_graph hr_graph hypnogram_graph bodyposition_graph, ///
          xcommon ///
          cols(1) ///
          graphregion(fcolor(white) lcolor(white) lwidth(none) ilwidth(none) margin(zero)) ///
          plotregion(fcolor(white) lcolor(black) lwidth(none) ilwidth(none) margin(vsmall)) ///
          imargin(zero) ///
          name(oxygen_hr_hypnogram, replace)

      Comment

      Working...
      X