Announcement

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

  • marginsplot: individual marker color/filling if difference is significant

    I estimate a model for the probability of never being married with an interaction of two categorical variables, say race (White/Black/Other) and collgrad (Not College Grad/College Grad).
    A familiar problem with the graphical representation of the results is that the plotted confidence intervals might be misleading for judging whether a difference between two groups is statistically significant. Hence, I omit them from the plot and use margins contrast to provide test statistics for the differences between the various groups. In this example, the difference between Blacks and Whites within the group of Non-College Grads is significant.
    Now I would like to include this information in the marginsplot by filling the individual marker for Blacks within the Non-College Grads group or by changing its color. How would I do that (besides manual editing)?
    Andrew provides some guidance for a similar case (https://www.statalist.org/forums/forum/general-stata-discussion/general/1416513-vary-marker-color-in-marginsplot). The difference to my case is that I use marginsplot to display the group levels but obtain the information on the significant differences between them from a different command. How would I combine them?

    Code:
    sysuse nlsw88, clear
    reg never_married i.race##i.collgrad
    margins race#collgrad, dydx()
    marginsplot, recast(scatter) x(collgrad) noci plot1opts(msymbol(Oh)) plot2opts(msymbol(Dh)) plot3opts(msymbol(Sh)) title("") ytitle("Never married")
    reg never_married i.race##i.collgrad
    margins r.race@collgrad, contrast(nowald pveffects) post

  • #2
    If you want to save the results from both margins commands, combine them, and then plot using twoway with a condition for shading the markers, here is one way to do it. The values in the data example are labeled, but I am not sure whether this generalizes to unlabeled values.

    Code:
    sysuse nlsw88, clear
    reg never_married i.race##i.collgrad
    margins race#collgrad, dydx() saving(results1, replace)
    marginsplot, recast(scatter) x(collgrad) noci plot1opts(msymbol(Oh)) plot2opts(msymbol(Dh)) plot3opts(msymbol(Sh)) title("") ytitle("Never married")
    reg never_married i.race##i.collgrad
    margins r.race@collgrad, contrast(nowald pveffects) post saving(results2, replace)
    
    use results2, clear
    rename _pvalue _p
    foreach var of varlist _m?{
        decode `var', gen(`=upper("`var'")')
        replace `=upper("`var'")'= trim(itrim(ustrregexra(`=upper("`var'")', "(.*)\bvs\b.*", "$1")))
    }
    
    keep _p _M*
    save results2, replace
    use results1, clear
    foreach var of varlist _m?{
        decode `var', gen(`=upper("`var'")')
    }
    merge 1:1 _M* using results2
    
    twoway (scatter _margin _m2 if _m1==1, sort mc(blue) msy(Oh)) ///
    (scatter _margin _m2 if _m1==1 & _p<0.01, sort mc(blue) msy(O)) ///
    (scatter _margin _m2 if _m1==2, sort mc(red) msy(Dh)) ///
    (scatter _margin _m2 if _m1==2 & _p<0.01, sort mc(red) msy(D)) ///
    (scatter _margin _m2 if _m1==3, sort mc(black) msy(Sh)) ///
    (scatter _margin _m2 if _m1==3 & _p<0.01, mc(black) msy(S)), ///
    legend(order(1 "White" 3 "Black" 5 "Other")) title("Predictive Margins") ///
    ytitle("Linear Prediction") xla(0/1, valuelabel) xsc(r(. 1.05)) xtitle("") ///
    note("Filled in markers indicate significance relative to base (White) at the 1% level")
    Click image for larger version

Name:	Graph.png
Views:	1
Size:	28.1 KB
ID:	1761115

    Last edited by Andrew Musau; 08 Aug 2024, 18:38.

    Comment


    • #3
      Dear Andrew,

      My suggestion is to also include in the legend the color coded marker symbols that indicate significance as to further enhance this fine example, like:
      Code:
      ...
      legend(order(1 "White" 3 "Black" 5 "Other" 2 "sig." 4 "sig." 6 "sig." )) title("Predictive Margins") ///
      ...
      http://publicationslist.org/eric.melse

      Comment


      • #4
        Many thanks, Andrew, this is working wonderfully.

        Eric, I think I see what you are aiming at. In order to economize on the legend space, would it be possible to place the hollow and the filled marker symbols for each group next to each other, followed by the group label?

        Comment


        • #5
          Yes Andreas, that is possible.

          Alternative one positions the marker symbols below each other, using:
          Code:
          legend(order(1 "" 2 "White" 3 "" 4 "Black" 5 "" 6 "Other")) title("Predictive Margins") ///
          It is necessary to include two double quotes after the first marker code number to prevent Stata to use the default option to include the marker label, e.g. 1 ""

          Alternative two positions the marker symbols after each other, using:
          Code:
          legend(order(1 "" 2 "White" 3 "" 4 "Black" 5 "" 6 "Other") col(2) colgap(.5)) title("Predictive Margins") ///
          To get this result we have to set the number of columns using col(2) and colgap(.5) to control the distance between the two marker symbols.

          There are a lot of options available to control the lay out of the legend, use h legend_options to read more about that.
          Also I can recommend the book written by Michael Mitchell - A Visual Guide to Stata Graphics - to learn more about coding graphs/plots.
          http://publicationslist.org/eric.melse

          Comment


          • #6
            Thanks, Eric, that's very helpful and it's working!

            A final modification: How would I properly omit the filled marker for the White baseline group, given that I wouldn't need it, as I only want to highlight significant deviations from the baseline? I've managed to omit the filled marker by using:

            Code:
             
             legend(order(1 "White" 3 "" 4 "Black" 5 "" 6 "Other") col(2) colgap(.5) holes(1)) title("Predictive Margins") ///
            but then the hollow markers aren't stacked above anymore as neatly as before.

            Comment


            • #7
              Andreas,

              For such result we have to use the 'invisible marker' symbol, using msy(i) instead of any other, like msy(O), using the example code:

              Code:
              twoway (scatter _margin _m2 if _m1==1, sort mc(blue) msy(Oh)) ///
              (scatter _margin _m2 if _m1==1 & _p<0.01, sort mc(blue) msy(i)) ///
              (scatter _margin _m2 if _m1==2, sort mc(red) msy(Dh)) ///
              (scatter _margin _m2 if _m1==2 & _p<0.01, sort mc(red) msy(D)) ///
              (scatter _margin _m2 if _m1==3, sort mc(black) msy(Sh)) ///
              (scatter _margin _m2 if _m1==3 & _p<0.01, mc(black) msy(i)), ///
              xsize(5) ysize(4) plotregion(m(l+25 r+20)) /// Adjustment of the plot positioning
              legend(order(1 "" 2 "White" 3 "" 4 "Black" 5 "" 6 "Other") col(2) colgap(.5)) title("Predictive Margins") ///
              ytitle("Linear Prediction") xla(0/1, valuelabel) xsc(r(. 1.05)) xtitle("") ///
              note("Filled in markers indicate significance relative to base (White) at the 1% level")
              which results in:

              Click image for larger version

Name:	Example_filled_in_markers_indicate_sign.png
Views:	1
Size:	49.1 KB
ID:	1761255

              Ofcourse, this is very much specific to your case, i.e. how and when to adjust the marker symbol to be invisible of a particular group.
              On a side note, I would not use the color red to code 'Black', which could create word-color perception issues as well as color appreciation issues (using red as a signal for Black(?)).
              http://publicationslist.org/eric.melse

              Comment


              • #8
                Wonderful, thanks!
                No worries, both variables and marker colorings are serving purely as examples here.

                Comment

                Working...
                X