title: SAS GRAPH: align axis for 2 plots with lattice rows
body: <p>I'm really struggling myself with this problem, I really can't find a solution and I hope that, posting here, someone will help.</p>
  
  <p>The problem is that with this 2-lattice-rows template I can't align the axis. </p>
  
  <p><a href="https://i.stack.imgur.com/yDjSK.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yDjSK.gif" alt="BIG PROBLEM"></a></p>
  
  <p>Now I detail everything I did with code to reproduce each step:</p>
  
  <p>I have this plot <a href="https://i.stack.imgur.com/jgiAQ.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jgiAQ.gif" alt="First_plot"></a></p>
  
  <p>Here the code both for the graph and for the sample dataset (it's a simple version of this: <a href="http://support.sas.com/kb/39/092.html" rel="nofollow noreferrer">http://support.sas.com/kb/39/092.html</a>).</p>
  
  <p>Sample dataset:</p>
  
  <pre><code>data immune;
     format sival f6.3;
     input trt $ 1-8 cyc $ 10-18 pt lbparm $ xval sival;
     cards;
  Drug A   Cycle 1   1   C3  1   1.120
  Drug A   Cycle 1   1   C4  1   0.147
  Drug A   Cycle 1   1   C3  2   1.080
  Drug A   Cycle 1   1   C4  2   0.131
  Drug A   Cycle 1   1   C3  3   0.887
  Drug A   Cycle 1   1   C4  3   0.113
  Drug A   Cycle 2   1   C3  4   1.440
  Drug A   Cycle 2   1   C4  4   0.278
  Drug A   Cycle 2   1   C3  5   1.180
  Drug A   Cycle 2   1   C4  5   0.234
  Drug A   Cycle 2   1   C3  6   1.360
  Drug A   Cycle 2   1   C4  6   0.281
  Drug A   Cycle 3   1   C3  7   1.190
  Drug A   Cycle 3   1   C4  7   0.282
  Drug A   Cycle 3   1   C3  8   1.000
  Drug A   Cycle 3   1   C4  8   0.228
  Drug A   Cycle 3   1   C3  9   1.040
  Drug A   Cycle 3   1   C4  9   0.228
  Drug A   Cycle 4   1   C3 10   0.917
  Drug A   Cycle 4   1   C4 10   0.163
  Drug A   Cycle 4   1   C3 11   0.789
  Drug A   Cycle 4   1   C4 11   0.136
  Drug A   Cycle 4   1   C3 12   0.861
  Drug A   Cycle 4   1   C4 12   0.148
  Drug A   Cycle 1   2   C3  1   1.180
  Drug A   Cycle 1   2   C4  1   0.264
  Drug A   Cycle 1   2   C3  2   0.942
  Drug A   Cycle 1   2   C4  2   0.184
  Drug A   Cycle 1   2   C3  3   1.010
  Drug A   Cycle 1   2   C4  3   0.160
  Drug A   Cycle 2   2   C3  4   1.050
  Drug A   Cycle 2   2   C4  4   0.134
  Drug A   Cycle 2   2   C3  5   0.980
  Drug A   Cycle 2   2   C4  5   0.120
  Drug A   Cycle 2   2   C3  6   1.020
  Drug A   Cycle 2   2   C4  6   0.126
  Drug A   Cycle 3   2   C3  7   0.961
  Drug A   Cycle 3   2   C4  7   0.110
  Drug A   Cycle 3   2   C3  8   0.859
  Drug A   Cycle 3   2   C4  8   0.091
  Drug A   Cycle 3   2   C3  9   0.928
  Drug A   Cycle 3   2   C4  9   0.097
  Drug A   Cycle 4   2   C3 10   1.380
  Drug A   Cycle 4   2   C4 10   0.330
  Drug A   Cycle 4   2   C3 11   1.210
  Drug A   Cycle 4   2   C4 11   0.281
  Drug A   Cycle 4   2   C3 12   1.180
  Drug A   Cycle 4   2   C4 12   0.278
  Drug A   Cycle 1   3   C3  1   1.180
  Drug A   Cycle 1   3   C4  1   0.269
  Drug A   Cycle 1   3   C3  2   1.010
  Drug A   Cycle 1   3   C4  2   0.213
  Drug A   Cycle 1   3   C3  3   1.040
  Drug A   Cycle 1   3   C4  3   0.200
  Drug A   Cycle 2   3   C3  4   1.200
  Drug A   Cycle 2   3   C4  4   0.332
  Drug A   Cycle 2   3   C4  5   0.371
  Drug A   Cycle 2   3   C4  6   0.316
  Drug A   Cycle 3   3   C4  7   0.271
  Drug A   Cycle 3   3   C3  8   1.050
  Drug A   Cycle 3   3   C4  8   0.246
  Drug A   Cycle 3   3   C3  9   1.100
  Drug A   Cycle 3   3   C4  9   0.248
  Drug A   Cycle 4   3   C3 10   1.090
  Drug A   Cycle 4   3   C4 10   0.234
  Drug A   Cycle 4   3   C3 11   0.937
  Drug A   Cycle 4   3   C3 12   0.980
  Drug A   Cycle 1   4   C3  1   1.220
  Drug A   Cycle 1   4   C4  1   0.182
  Drug A   Cycle 1   4   C3  2   0.983
  Drug A   Cycle 1   4   C4  2   0.132
  Drug A   Cycle 1   4   C3  3   0.979
  Drug A   Cycle 1   4   C4  3   0.128
  Drug A   Cycle 2   4   C3  4   1.190
  Drug A   Cycle 2   4   C4  4   0.134
  Drug A   Cycle 2   4   C3  5   1.010
  Drug A   Cycle 2   4   C4  5   0.076
  Drug A   Cycle 2   4   C3  6   1.100
  Drug A   Cycle 2   4   C4  6   0.083
  Drug A   Cycle 3   4   C3  7   1.140
  Drug A   Cycle 3   4   C4  7   0.108
  Drug A   Cycle 3   4   C3  8   1.140
  Drug A   Cycle 3   4   C4  8   0.104
  Drug A   Cycle 3   4   C3  9   1.120
  Drug A   Cycle 3   4   C4  9   0.080
  ;
  run;
  
  proc sort data=immune out=sasuser.immune;
     by pt;
  run;
  </code></pre>
  
  <p>Now the template code for the graph:</p>
  
  <pre><code>proc template;
    define statgraph gsv00251;
      begingraph / designwidth=7in designheight=4.5in;
        entrytitle 'Immunology Profile by Treatment';
        layout gridded;
          layout datalattice rowvar=lbparm /
                 headerlabeldisplay=value includemissingclass=false
                 columnaxisopts=(label="Cycle Day" griddisplay=on type=discrete
                 discreteopts=(tickdisplaylist=
                 ("0" "15" "30" "0" "15" "30" "0" "15" "30" "0" "15" "30"))  
                 offsetmin = .03 offsetmax = .03)
                 rowaxisopts=(offsetmax=.1 label="Values Converted to SI Units "
                 griddisplay=on) rowdatarange=union;
          layout prototype;
            blockplot x=xval block=cyc / datatransparency = .75
                                         display=(outline fill ) 
                                         name="block" filltype=alternate;
            seriesplot x=xval y=sival / group=pt index=pt name='a'
                                        display=all lineattrs=(pattern=1 thickness=2) 
                                        markerattrs=(symbol=circlefilled size=8);    
          endlayout;
          endlayout;
          entry ' ';
          discretelegend 'a' / title='Patient' across=8;
        endlayout; 
      endgraph;
    end;
  run;
  </code></pre>
  
  <p>Now I'd like to add some information on the top of each block, so I went through some searches on the web and I found out that the best way to achieve this result is to change the proc template, adding 2 lattice rows:</p>
  
  <p>1) the first lattice row containing a blockplot with these informations like in this plot <a href="https://support.sas.com/documentation/cdl/en/grstatug/62464/HTML/default/viewer.htm#n07sfa0fbx6yh5n1dyutt7boc3kp.htm" rel="nofollow noreferrer">https://support.sas.com/documentation/cdl/en/grstatug/62464/HTML/default/viewer.htm#n07sfa0fbx6yh5n1dyutt7boc3kp.htm</a> (the one with boxplots and statistics, the second example).</p>
  
  <p>2) the second lattice row containing the previously posted plot.</p>
  
  <p>So I created this raw sample dataset:</p>
  
  <pre><code>data firstrow;
  length ROW $20 TITLE $20 REASON $50 CHAR $20 VAR $20;
  infile datalines dlm=',';
  input ROW TITLE REASON CHAR VAR;
  datalines;
  ROW 1,ROW 1,FIRST REASON,FIRST ROW,FIRST VAR,
  ROW 2,ROW 2,SECOND REASON,SECOND ROW,SECOND VAR,
  ROW 3,ROW 3,THIRD REASON,THIRD ROW,THIRD VAR,
  ROW 4,ROW 4,FOURTH REASON,FOURTH ROW,FOURTH VAR,
  ;
  proc transpose data=firstrow out=firstrow_;
  by row;
  var title reason char var;
  run;
  </code></pre>
  
  <p>and merged (no by) it with the previous dataset:</p>
  
  <pre><code>proc sort data=immune out=immune;
     by pt;
  run;
  
  data immune;
  merge immune firstrow_;
  run;
  </code></pre>
  
  <p>then modified the proc template adding <code>layout lattice</code> and the blockplot.</p>
  
  <pre><code>proc template;
    define statgraph gsv00251;
      begingraph / designwidth=7in designheight=4.5in;
        entrytitle 'Immunology Profile by Treatment';
  
       layout lattice / columns=1 rowweights=(.15 .85);
                blockplot x=row block=col1  / class=_name_
                          datatransparency = .75
                          display=(outline fill values label)
                          name="stats" filltype=alternate 
                          valuehalign=center
                          includemissingclass=false
                          labelattrs=GraphDataText valueattrs=GraphDataText ;
        layout gridded;
          layout datalattice rowvar=lbparm /
                 headerlabeldisplay=value includemissingclass=false
                 columnaxisopts=(label="Cycle Day" griddisplay=on type=discrete
                 discreteopts=(tickdisplaylist=
                 ("0" "15" "30" "0" "15" "30" "0" "15" "30" "0" "15" "30"))  
                 offsetmin = .03 offsetmax = .03)
                 rowaxisopts=(offsetmax=.1 label="Values Converted to SI Units "
                 griddisplay=on) rowdatarange=union;
          layout prototype;
            blockplot x=xval block=cyc / datatransparency = .75
                                         display=(outline fill ) 
                                         name="block" filltype=alternate;
            seriesplot x=xval y=sival / group=pt index=pt name='a'
                                        display=all lineattrs=(pattern=1 thickness=2) 
                                        markerattrs=(symbol=circlefilled size=8);    
          endlayout;
          endlayout;
          entry ' ';
          discretelegend 'a' / title='Patient' across=8;
        endlayout; 
  
      endlayout;
  
      endgraph;
    end;
  run;
  </code></pre>
  
  <p>The result is good but not least, I mean, the column axis is not aligned with the two plots, the result is the first plot posted.</p>
  
  <p>There are basically 2 issues: header labels on the right and axis label on the left. Howe can I change this plot, to gain the correct result? (axis aligned)</p>
  
  <p>Since I posted a lot of code, here you will find only the final version of all this</p>
  
  <pre><code> data immune;
     format sival f6.3;
     input trt $ 1-8 cyc $ 10-18 pt lbparm $ xval sival;
     cards;
  Drug A   Cycle 1   1   C3  1   1.120
  Drug A   Cycle 1   1   C4  1   0.147
  Drug A   Cycle 1   1   C3  2   1.080
  Drug A   Cycle 1   1   C4  2   0.131
  Drug A   Cycle 1   1   C3  3   0.887
  Drug A   Cycle 1   1   C4  3   0.113
  Drug A   Cycle 2   1   C3  4   1.440
  Drug A   Cycle 2   1   C4  4   0.278
  Drug A   Cycle 2   1   C3  5   1.180
  Drug A   Cycle 2   1   C4  5   0.234
  Drug A   Cycle 2   1   C3  6   1.360
  Drug A   Cycle 2   1   C4  6   0.281
  Drug A   Cycle 3   1   C3  7   1.190
  Drug A   Cycle 3   1   C4  7   0.282
  Drug A   Cycle 3   1   C3  8   1.000
  Drug A   Cycle 3   1   C4  8   0.228
  Drug A   Cycle 3   1   C3  9   1.040
  Drug A   Cycle 3   1   C4  9   0.228
  Drug A   Cycle 4   1   C3 10   0.917
  Drug A   Cycle 4   1   C4 10   0.163
  Drug A   Cycle 4   1   C3 11   0.789
  Drug A   Cycle 4   1   C4 11   0.136
  Drug A   Cycle 4   1   C3 12   0.861
  Drug A   Cycle 4   1   C4 12   0.148
  Drug A   Cycle 1   2   C3  1   1.180
  Drug A   Cycle 1   2   C4  1   0.264
  Drug A   Cycle 1   2   C3  2   0.942
  Drug A   Cycle 1   2   C4  2   0.184
  Drug A   Cycle 1   2   C3  3   1.010
  Drug A   Cycle 1   2   C4  3   0.160
  Drug A   Cycle 2   2   C3  4   1.050
  Drug A   Cycle 2   2   C4  4   0.134
  Drug A   Cycle 2   2   C3  5   0.980
  Drug A   Cycle 2   2   C4  5   0.120
  Drug A   Cycle 2   2   C3  6   1.020
  Drug A   Cycle 2   2   C4  6   0.126
  Drug A   Cycle 3   2   C3  7   0.961
  Drug A   Cycle 3   2   C4  7   0.110
  Drug A   Cycle 3   2   C3  8   0.859
  Drug A   Cycle 3   2   C4  8   0.091
  Drug A   Cycle 3   2   C3  9   0.928
  Drug A   Cycle 3   2   C4  9   0.097
  Drug A   Cycle 4   2   C3 10   1.380
  Drug A   Cycle 4   2   C4 10   0.330
  Drug A   Cycle 4   2   C3 11   1.210
  Drug A   Cycle 4   2   C4 11   0.281
  Drug A   Cycle 4   2   C3 12   1.180
  Drug A   Cycle 4   2   C4 12   0.278
  Drug A   Cycle 1   3   C3  1   1.180
  Drug A   Cycle 1   3   C4  1   0.269
  Drug A   Cycle 1   3   C3  2   1.010
  Drug A   Cycle 1   3   C4  2   0.213
  Drug A   Cycle 1   3   C3  3   1.040
  Drug A   Cycle 1   3   C4  3   0.200
  Drug A   Cycle 2   3   C3  4   1.200
  Drug A   Cycle 2   3   C4  4   0.332
  Drug A   Cycle 2   3   C4  5   0.371
  Drug A   Cycle 2   3   C4  6   0.316
  Drug A   Cycle 3   3   C4  7   0.271
  Drug A   Cycle 3   3   C3  8   1.050
  Drug A   Cycle 3   3   C4  8   0.246
  Drug A   Cycle 3   3   C3  9   1.100
  Drug A   Cycle 3   3   C4  9   0.248
  Drug A   Cycle 4   3   C3 10   1.090
  Drug A   Cycle 4   3   C4 10   0.234
  Drug A   Cycle 4   3   C3 11   0.937
  Drug A   Cycle 4   3   C3 12   0.980
  Drug A   Cycle 1   4   C3  1   1.220
  Drug A   Cycle 1   4   C4  1   0.182
  Drug A   Cycle 1   4   C3  2   0.983
  Drug A   Cycle 1   4   C4  2   0.132
  Drug A   Cycle 1   4   C3  3   0.979
  Drug A   Cycle 1   4   C4  3   0.128
  Drug A   Cycle 2   4   C3  4   1.190
  Drug A   Cycle 2   4   C4  4   0.134
  Drug A   Cycle 2   4   C3  5   1.010
  Drug A   Cycle 2   4   C4  5   0.076
  Drug A   Cycle 2   4   C3  6   1.100
  Drug A   Cycle 2   4   C4  6   0.083
  Drug A   Cycle 3   4   C3  7   1.140
  Drug A   Cycle 3   4   C4  7   0.108
  Drug A   Cycle 3   4   C3  8   1.140
  Drug A   Cycle 3   4   C4  8   0.104
  Drug A   Cycle 3   4   C3  9   1.120
  Drug A   Cycle 3   4   C4  9   0.080
  ;
  run;
  
  
  data firstrow;
  length ROW $20 TITLE $20 REASON $50 CHAR $20 VAR $20;
  infile datalines dlm=',';
  input ROW TITLE REASON CHAR VAR;
  datalines;
  ROW 1,ROW 1,FIRST REASON,FIRST ROW,FIRST VAR,
  ROW 2,ROW 2,SECOND REASON,SECOND ROW,SECOND VAR,
  ROW 3,ROW 3,THIRD REASON,THIRD ROW,THIRD VAR,
  ROW 4,ROW 4,FOURTH REASON,FOURTH ROW,FOURTH VAR,
  ;
  
  proc transpose data=firstrow out=firstrow_;
  by row;
  var title reason char var;
  run;
  
  proc sort data=immune out=immune;
     by pt;
  run;
  
  data immune;
  merge immune firstrow_;
  run;
  
  proc template;
    define statgraph gsv00251;
      begingraph / designwidth=7in designheight=4.5in;
        entrytitle 'Immunology Profile by Treatment';
  
       layout lattice / columns=1 rowweights=(.15 .85);
                  columnaxes;
                      columnaxis / display=(ticks tickvalues);
                  endcolumnaxes;
  
  
  
                blockplot x=row block=col1  / class=_name_
                          datatransparency = .75
                          display=(outline fill values label)
                          name="stats" filltype=alternate 
                          valuehalign=center
                          includemissingclass=false
                          labelattrs=GraphDataText valueattrs=GraphDataText ;
        layout gridded;
          layout datalattice rowvar=lbparm /
                 headerlabeldisplay=value includemissingclass=false
                 columnaxisopts=(label="Cycle Day" griddisplay=on type=discrete
                 discreteopts=(tickdisplaylist=
                 ("0" "15" "30" "0" "15" "30" "0" "15" "30" "0" "15" "30"))  
                 offsetmin = .03 offsetmax = .03)
                 rowaxisopts=(offsetmax=.1 label="Values Converted to SI Units "
                 griddisplay=on) rowdatarange=union;
          layout prototype;
            blockplot x=xval block=cyc / datatransparency = .75
                                         display=(outline fill ) 
                                         name="block" filltype=alternate;
            seriesplot x=xval y=sival / group=pt index=pt name='a'
                                        display=all lineattrs=(pattern=1 thickness=2) 
                                        markerattrs=(symbol=circlefilled size=8);    
          endlayout;
          endlayout;
          entry ' ';
          discretelegend 'a' / title='Patient' across=8;
        endlayout; 
  
      endlayout;
  
      endgraph;
    end;
  run;
  ods listing close;
  ods html image_dpi=100 file='Immunology.html' path='.';
  ods graphics / reset noborder width=600px height=400px 
    imagename='ClinicalHandout_Immunology' imagefmt=gif noscale;
  
  proc sgrender data=immune template=gsv00251; 
  run;
  ods html close;
  ods listing;
  </code></pre>