Announcement

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

  • Adding empty legend to marginsplot to align y axes in combined graph

    I want to combine two marginsplots in a single graph. One of them (Graph 1) is a conditional effects plot with two lines illustrating an interaction effect. The other (Graph 2) is a simpler main effect, predictive margins plot with a single line. While Graph 1 is rendered with a legend for the two lines, Graph 2 (correctly) does not have a legend -- which is why its y axis (which is on the same scale as that of Graph 1) extends further down, filling the empty space filled by the legend in Graph 1. This is what I am trying to prevent.

    I have tried using the legend options for Graph 2 to add an "empty" legend to prevent the y axis from extend further down, but they have been ignored by Stata. Using the -label- suboption as proposed here does not work:

    Code:
    marginsplot, recast(line) title("Graph 2") ///
    plot( , label("does not appear")) ///
    xtitle("appears", height(5)) ///
    yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("appears")
    Neither does the -order- suboption of -legend- as proposed here:

    Code:
    marginsplot, recast(line) title("Graph 2") ///
    plotopts(lwidth(medium) legend(order(3 "does not" 4 "appear"))) ///
    xtitle("appears", height(5)) ///
    yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("appears")
    I am sure I am missing something really basic here, but since no amount of searching and manual inspection is helping, I'd appreciate if someone can spot what is going here, and how I could align the y axis of the graph without legend to the y axis of the graph with a legend. Any help is much appreciated!

  • #2
    Since no one has responded thus far, let me clarify that unlike the title of the original post may suggest I am not necessarily seeking a solution to the problem outlined above that makes use of an empty legend. Any solution that aligns the y axes of the two twoway graphs (in the sense of ensuring a 1:1 proportion of their lengths) will be appreciated. Also, if part of the problem is not understandable and/or additional information is needed, please let me know.

    Comment


    • #3
      Since there are still no responses, I would be happy to know why. Is the problem description lacking information needed to come up with a proper solution that I am overlooking? Is the problem too basic without me realizing? Or is there simply no explanation and/or solution for the problem described in the original post? Any help is appreciated.

      Comment


      • #4
        Can you provide a reproducible example using a stock dataset (like webuse auto.dta, or see http://www.stata-press.com/data/r9/d.html for some common Stata manual datasets)? It is much easier to help you find a solution if we have a toy example to play with. Also, please provide the code you use to combine the datasets. graph combine has a lot of options that might help (see help graph combine), and it is useful to see what you have tried.
        Stata/MP 14.1 (64-bit x86-64)
        Revision 19 May 2016
        Win 8.1

        Comment


        • #5
          I just used the auto dataset and constructed an analog to the situation described above. Code pasted below. Note how the y axis of the main effect graph (Plot a.) extends further down than the y axis of the conditional effect graph (Plot b.). Both should have equal length and align.

          Code:
          webuse auto.dta, clear
          
          * Generate binary outcome
          sort mpg
          gen mpg_bin = _n > _N/2
          
          * Plot a
          logit mpg_bin i.foreign c.headroom    // estimate logit model
          
          margins, at(headroom=(1.5(.5)5))    // calculate predictive margins
          
          marginsplot, level(95) recastci(rarea) recast(line) title("a. Headroom main") ///
          xtitle("Headroom (in.)", height(5)) ///
          yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("P(hi-mpg)") ///
          name(headmain, replace) scheme(s1mono)
          
          * Plot b
          logit mpg_bin i.foreign##c.headroom    // estimate logit model
          
          margins foreign, at(headroom=(1.5(.5)5))    // calculate predictive margins
          
          marginsplot, level(95) recastci(rarea) recast(line) title("a. Head x foreign") ///
          xtitle("Headroom (in.)", height(5)) ///
          yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("P(hi-mpg)") ///
          name(headXforeign, replace) scheme(s1mono)
          
          * Combine Plots a. and b.
          graph combine headmain headXforeign    // combined graph

          Comment


          • #6
            Great, this is very helpful!

            I see two options:

            1) Move the legend to the right of the 2nd graph. This isn't very pretty, but it solves the y-axis issue:
            Code:
            marginsplot, level(95) recastci(rarea) recast(line) title("a. Head x foreign") ///
            xtitle("Headroom (in.)", height(5)) ///
            yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("P(hi-mpg)") ///
            name(headXforeign, replace) scheme(s1mono) legend(pos(2) cols(1))
            
            * Combine Plots a. and b.
            graph combine headmain headXforeign , ycommon

            2) A much better option, I think, is to download Vince Wiggins' grc1leg program that provides a common legend for a combined graph

            Code:
            net describe grc1leg, from(http://www.stata.com/users/vwiggins)
            *or
            findit grc1leg
            Using this, you can do the following:
            Code:
            grc1leg headmain headXforeign , ycommon legendfrom(headXforeign)
            Stata/MP 14.1 (64-bit x86-64)
            Revision 19 May 2016
            Win 8.1

            Comment


            • #7
              Thank you for the input!

              Option 1 works as described, but I agree on the aesthetics -- not too appealing since it compresses the x axis of Plot b.

              Option 2 also works fine (and -grc1leg- seems like a very useful package I did not previously know -- thanks!) and it would be great IF the plots plotted lines for the same observations. But in the situation here, we have one plot for the main effect across all observations (Plot a.) and one for the interactive effect that divides the observations into two groups (Plot b.). In the example, the common legend makes it look as if Plot a. plotted the effect for a subset of obs - domestic cars - only (see below, I have excised the CIs to make the plots clearer).

              Code:
              webuse auto.dta, clear
              
              * Generate binary outcome
              sort mpg
              gen mpg_bin = _n > _N/2
              
              * Plot 1
              logit mpg_bin i.foreign c.headroom    // estimate logit model
              margins, at(headroom=(1.5(.5)5))    // calculate predictive margins
              marginsplot, noci level(95) recastci(rarea) recast(line) title("a. Headroom main") ///
              xtitle("Headroom (in.)", height(5)) ///
              yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("P(hi-mpg)") ///
              name(headmain, replace) scheme(s1mono)
              
              * Plot b
              logit mpg_bin i.foreign##c.headroom
              
              margins foreign, at(headroom=(1.5(.5)5))
              marginsplot, noci level(95) recastci(rarea) recast(line) title("a. Head x foreign") ///
              xtitle("Headroom (in.)", height(5)) ///
              yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("P(hi-mpg)") ///
              name(headXforeign, replace) scheme(s1mono)
              
              
              * Combine Plots a. and b.
              grc1leg headmain headXforeign , ycommon legendfrom(headXforeign) graphregion(color(white)) // combined graph w/ single legend
              Ideally, the legend for Plot b. would appear only below Plot b. (no legend for Plot a.) or inside its plot region. Can this be done?

              Comment


              • #8
                Try:

                Code:
                * Combine Plots a. and b.
                grc1leg headmain headXforeign , ycommon legendfrom(headXforeign) graphregion(color(white)) pos(5)   // combined graph w/ single legend
                or

                Code:
                * Plot b
                logit mpg_bin i.foreign##c.headroom
                
                margins foreign, at(headroom=(1.5(.5)5))
                marginsplot, noci level(95) recastci(rarea) recast(line) title("a. Head x foreign") ///
                xtitle("Headroom (in.)", height(5)) ///
                yscale(r(0 1)) ylabel(0(.2)1, grid) ytitle("P(hi-mpg)")  ///
                name(headXforeign, replace) scheme(s1mono) legend(col(1))
                
                
                * Combine Plots a. and b.
                grc1leg headmain headXforeign , ycommon legendfrom(headXforeign) graphregion(color(white)) pos(5)  // combined graph w/ single legend
                Stata/MP 14.1 (64-bit x86-64)
                Revision 19 May 2016
                Win 8.1

                Comment


                • #9
                  This last step really helped once more -- initial problem is now solved and the legend put where it belongs (under Plot b.). Thank you so much for your input from start to finish, Carole, I really appreciate it!

                  Comment

                  Working...
                  X